/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties {
  @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
    *, :before, :after, ::backdrop {
      --tw-translate-x: 0;
      --tw-translate-y: 0;
      --tw-translate-z: 0;
      --tw-scale-x: 1;
      --tw-scale-y: 1;
      --tw-scale-z: 1;
      --tw-rotate-x: initial;
      --tw-rotate-y: initial;
      --tw-rotate-z: initial;
      --tw-skew-x: initial;
      --tw-skew-y: initial;
      --tw-scroll-snap-strictness: proximity;
      --tw-space-y-reverse: 0;
      --tw-divide-y-reverse: 0;
      --tw-border-style: solid;
      --tw-leading: initial;
      --tw-font-weight: initial;
      --tw-tracking: initial;
      --tw-ordinal: initial;
      --tw-slashed-zero: initial;
      --tw-numeric-figure: initial;
      --tw-numeric-spacing: initial;
      --tw-numeric-fraction: initial;
      --tw-shadow: 0 0 #0000;
      --tw-shadow-color: initial;
      --tw-shadow-alpha: 100%;
      --tw-inset-shadow: 0 0 #0000;
      --tw-inset-shadow-color: initial;
      --tw-inset-shadow-alpha: 100%;
      --tw-ring-color: initial;
      --tw-ring-shadow: 0 0 #0000;
      --tw-inset-ring-color: initial;
      --tw-inset-ring-shadow: 0 0 #0000;
      --tw-ring-inset: initial;
      --tw-ring-offset-width: 0px;
      --tw-ring-offset-color: #fff;
      --tw-ring-offset-shadow: 0 0 #0000;
      --tw-outline-style: solid;
      --tw-blur: initial;
      --tw-brightness: initial;
      --tw-contrast: initial;
      --tw-grayscale: initial;
      --tw-hue-rotate: initial;
      --tw-invert: initial;
      --tw-opacity: initial;
      --tw-saturate: initial;
      --tw-sepia: initial;
      --tw-drop-shadow: initial;
      --tw-drop-shadow-color: initial;
      --tw-drop-shadow-alpha: 100%;
      --tw-drop-shadow-size: initial;
      --tw-backdrop-blur: initial;
      --tw-backdrop-brightness: initial;
      --tw-backdrop-contrast: initial;
      --tw-backdrop-grayscale: initial;
      --tw-backdrop-hue-rotate: initial;
      --tw-backdrop-invert: initial;
      --tw-backdrop-opacity: initial;
      --tw-backdrop-saturate: initial;
      --tw-backdrop-sepia: initial;
      --tw-duration: initial;
      --tw-ease: initial;
    }
  }
}

@layer theme {
  :root, :host {
    --font-sans: "Switzer", system-ui, -apple-system, sans-serif;
    --font-serif: "Charter", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
    --font-mono: "SF Mono", ui-monospace, "Menlo", "Cascadia Mono", monospace;
    --color-red-100: oklch(93.6% .032 17.717);
    --color-red-600: oklch(57.7% .245 27.325);
    --color-orange-100: oklch(95.4% .038 75.164);
    --color-orange-600: oklch(64.6% .222 41.116);
    --color-yellow-100: oklch(97.3% .071 103.193);
    --color-yellow-500: oklch(79.5% .184 86.047);
    --color-yellow-600: oklch(68.1% .162 75.834);
    --color-green-100: oklch(96.2% .044 156.743);
    --color-green-500: oklch(72.3% .219 149.579);
    --color-green-600: oklch(62.7% .194 149.214);
    --color-blue-100: oklch(93.2% .032 255.585);
    --color-blue-500: oklch(62.3% .214 259.815);
    --color-blue-600: oklch(54.6% .245 262.881);
    --color-violet-100: oklch(94.3% .029 294.588);
    --color-violet-600: oklch(54.1% .281 293.009);
    --color-gray-700: oklch(37.3% .034 259.733);
    --color-neutral-200: oklch(92.2% 0 none);
    --color-neutral-300: oklch(87% 0 none);
    --color-neutral-400: oklch(70.8% 0 none);
    --color-neutral-500: oklch(55.6% 0 none);
    --color-neutral-800: oklch(26.9% 0 none);
    --color-black: #000;
    --color-white: #fff;
    --spacing: .25rem;
    --container-xs: 20rem;
    --container-md: 28rem;
    --container-lg: 32rem;
    --container-xl: 36rem;
    --container-2xl: 42rem;
    --container-3xl: 48rem;
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    --font-weight-extrabold: 800;
    --tracking-tight: -.025em;
    --tracking-normal: 0em;
    --leading-tight: 1.25;
    --leading-snug: 1.375;
    --leading-relaxed: 1.625;
    --radius-sm: .25rem;
    --radius-md: .375rem;
    --radius-lg: .5rem;
    --radius-xl: .75rem;
    --radius-2xl: 1rem;
    --shadow-lg: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;
    --ease-out: cubic-bezier(0, 0, .2, 1);
    --ease-in-out: cubic-bezier(.4, 0, .2, 1);
    --animate-pulse: pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;
    --blur-sm: 8px;
    --blur-md: 12px;
    --default-transition-duration: .15s;
    --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);
    --default-font-family: var(--font-sans);
    --default-mono-font-family: var(--font-mono);
    --color-ink-000: #0e0d12;
    --color-ink-050: #16151c;
    --color-ink-100: #1b1a22;
    --color-ink-200: #2a2833;
    --color-ink-150: #201e28;
    --color-ink-300: #3a3746;
    --color-ink-400: #8b8599;
    --color-ink-500: #9a94a8;
    --color-ink-600: #bdb8c8;
    --color-ink-900: #f0eef4;
    --color-beam: #22e0d5;
    --color-beam-dim: #22e0d521;
    --color-flag: #ff2e8e;
    --color-judge: #b49be8;
    --color-flag-dim: #ff2e8e21;
    --color-flag-canvas: #ff2e8e;
    --rail-outside: linear-gradient(180deg, var(--color-ink-400) 0 100%);
    --rail-own: repeating-linear-gradient(180deg,
    var(--color-beam) 0 7px,
    transparent 7px 11px);
    --rail-authored: repeating-linear-gradient(180deg,
    var(--color-ink-300) 0 3px,
    transparent 3px 6px);
    --color-cleared: #b8f04a;
    --color-select: #22e0d54d;
    --cursor-write: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='28' fill='none'%3E%3Cpath d='M10 5.5v17' stroke='%23e8e6e3' stroke-width='1.5'/%3E%3Cpath d='M6.5 4.75h7M6.5 23.25h7' stroke='%2322e0d5' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E")
    10 14;
    --gradient-dichroic: linear-gradient(103deg, #ff2e8e 0%, #8a3ffc 38%, #2b6bff 68%, #22e0d5 100%);
    --font-display: "Zodiak", "Charter", Georgia, serif;
    --radius-panel: 10px;
    --fill-judge: #363045;
  }

  @supports (color: color-mix(in lab, red, red)) {
    :root, :host {
      --fill-judge: color-mix(in srgb, var(--color-judge) 20%, var(--color-ink-050));
    }
  }

  :root, :host {
    --fill-cleared: #2e3623;
  }

  @supports (color: color-mix(in lab, red, red)) {
    :root, :host {
      --fill-cleared: color-mix(in srgb, var(--color-cleared) 15%, var(--color-ink-050));
    }
  }

  :root, :host {
    --grad-surface: linear-gradient(168deg, var(--color-ink-100), var(--color-ink-050) 70%);
    --wash-flag: linear-gradient(100deg, #ff2e8e17, transparent 46%);
    --wash-beam: linear-gradient(100deg, #22e0d514, transparent 46%);
    --wash-cleared: linear-gradient(100deg, #b8f04a14, transparent 46%);
  }
}

@layer base {
  *, :after, :before, ::backdrop {
    box-sizing: border-box;
    border: 0 solid;
    margin: 0;
    padding: 0;
  }

  ::file-selector-button {
    box-sizing: border-box;
    border: 0 solid;
    margin: 0;
    padding: 0;
  }

  html, :host {
    -webkit-text-size-adjust: 100%;
    tab-size: 4;
    line-height: 1.5;
    font-family: var(--default-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
    font-feature-settings: var(--default-font-feature-settings, normal);
    font-variation-settings: var(--default-font-variation-settings, normal);
    -webkit-tap-highlight-color: transparent;
  }

  hr {
    height: 0;
    color: inherit;
    border-top-width: 1px;
  }

  abbr:where([title]) {
    -webkit-text-decoration: underline dotted;
    text-decoration: underline dotted;
  }

  h1, h2, h3, h4, h5, h6 {
    font-size: inherit;
    font-weight: inherit;
  }

  a {
    color: inherit;
    -webkit-text-decoration: inherit;
    -webkit-text-decoration: inherit;
    -webkit-text-decoration: inherit;
    text-decoration: inherit;
  }

  b, strong {
    font-weight: bolder;
  }

  code, kbd, samp, pre {
    font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);
    font-feature-settings: var(--default-mono-font-feature-settings, normal);
    font-variation-settings: var(--default-mono-font-variation-settings, normal);
    font-size: 1em;
  }

  small {
    font-size: 80%;
  }

  sub, sup {
    vertical-align: baseline;
    font-size: 75%;
    line-height: 0;
    position: relative;
  }

  sub {
    bottom: -.25em;
  }

  sup {
    top: -.5em;
  }

  table {
    text-indent: 0;
    border-color: inherit;
    border-collapse: collapse;
  }

  :-moz-focusring:where(:not(iframe)) {
    outline: auto;
  }

  progress {
    vertical-align: baseline;
  }

  summary {
    display: list-item;
  }

  ol, ul, menu {
    list-style: none;
  }

  img, svg, video, canvas, audio, iframe, embed, object {
    vertical-align: middle;
    display: block;
  }

  img, video {
    max-width: 100%;
    height: auto;
  }

  button, input, select, optgroup, textarea {
    font: inherit;
    font-feature-settings: inherit;
    font-variation-settings: inherit;
    letter-spacing: inherit;
    color: inherit;
    opacity: 1;
    background-color: #0000;
    border-radius: 0;
  }

  ::file-selector-button {
    font: inherit;
    font-feature-settings: inherit;
    font-variation-settings: inherit;
    letter-spacing: inherit;
    color: inherit;
    opacity: 1;
    background-color: #0000;
    border-radius: 0;
  }

  :where(select:is([multiple], [size])) optgroup {
    font-weight: bolder;
  }

  :where(select:is([multiple], [size])) optgroup option {
    padding-inline-start: 20px;
  }

  ::file-selector-button {
    margin-inline-end: 4px;
  }

  ::placeholder {
    opacity: 1;
  }

  @supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) {
    ::placeholder {
      color: currentColor;
    }

    @supports (color: color-mix(in lab, red, red)) {
      ::placeholder {
        color: color-mix(in oklab, currentcolor 50%, transparent);
      }
    }
  }

  textarea {
    resize: vertical;
  }

  ::-webkit-search-decoration {
    -webkit-appearance: none;
  }

  ::-webkit-date-and-time-value {
    min-height: 1lh;
    text-align: inherit;
  }

  ::-webkit-datetime-edit {
    display: inline-flex;
  }

  ::-webkit-datetime-edit-fields-wrapper {
    padding: 0;
  }

  ::-webkit-datetime-edit {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-year-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-month-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-day-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-hour-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-minute-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-second-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-millisecond-field {
    padding-block: 0;
  }

  ::-webkit-datetime-edit-meridiem-field {
    padding-block: 0;
  }

  ::-webkit-calendar-picker-indicator {
    line-height: 1;
  }

  :-moz-ui-invalid {
    box-shadow: none;
  }

  button, input:where([type="button"], [type="reset"], [type="submit"]) {
    appearance: button;
  }

  ::file-selector-button {
    appearance: button;
  }

  ::-webkit-inner-spin-button {
    height: auto;
  }

  ::-webkit-outer-spin-button {
    height: auto;
  }

  [hidden]:where(:not([hidden="until-found"])) {
    display: none !important;
  }

  html, body, #root {
    height: 100%;
  }

  :root {
    color-scheme: dark;
  }

  body {
    background: var(--color-ink-000);
    color: var(--color-ink-900);
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    overscroll-behavior: none;
  }

  button:not(:disabled), [role="button"]:not(:disabled, [aria-disabled="true"]) {
    cursor: pointer;
  }

  :focus-visible:not(.copy-para, .slide [data-el], .studio-composer textarea) {
    outline-offset: 2px;
    outline: 2px solid var(--color-beam) !important;
  }

  ::selection {
    background: var(--color-select);
    color: var(--color-ink-900);
  }
}

@layer components {
  .i-display {
    font-family: var(--font-sans);
    letter-spacing: -.022em;
    color: var(--p-ink);
    text-wrap: balance;
    font-size: clamp(2rem, 3.8vw, 2.9rem);
    font-weight: 600;
    line-height: 1.08;
  }

  .i-title {
    font-family: var(--font-sans);
    letter-spacing: -.005em;
    color: var(--p-ink);
    text-wrap: balance;
    font-size: clamp(1.45rem, 2.4vw, 1.75rem);
    font-weight: 600;
    line-height: 1.25;
  }

  .i-subtitle {
    font-family: var(--font-sans);
    letter-spacing: -.01em;
    color: var(--p-ink);
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.3;
  }

  .i-lede {
    font-family: var(--font-sans);
    color: var(--p-ink);
    font-size: 19px;
    line-height: 32px;
  }

  .i-quiet {
    font-family: var(--font-sans);
    color: var(--p-ink-2);
    font-size: 15px;
    line-height: 26px;
  }

  .i-quote {
    font-family: var(--font-serif);
    color: var(--p-ink);
    font-size: 19px;
    line-height: 30px;
  }

  .i-body {
    font-family: var(--font-sans);
    color: var(--p-ink-2);
    font-size: 14.5px;
    line-height: 1.6;
  }

  .i-caption {
    font-family: var(--font-sans);
    color: var(--p-meta);
    font-size: 12.5px;
    line-height: 1.5;
  }

  .eyebrow-sans {
    font-family: var(--font-sans);
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--p-meta);
    font-size: 11px;
    font-weight: 600;
    line-height: 16px;
  }

  .i-label {
    font-family: var(--font-sans);
    color: var(--p-ink-2);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.4;
  }

  .instrument-site .tech {
    font-family: var(--font-mono);
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
    color: var(--color-ink-500);
    font-size: 11.5px;
    line-height: 16px;
  }

  .i-readout {
    font-family: var(--font-mono);
    letter-spacing: .13em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    color: var(--readout);
    font-size: 10.5px;
  }

  .i-measure {
    max-width: 620px;
  }

  .i-beat {
    margin-top: 48px;
  }

  .i-beat-title {
    margin-top: 40px;
  }

  .i-section {
    padding-top: 60px;
    padding-bottom: 60px;
  }

  @media (min-width: 1024px) {
    .i-section {
      padding-top: 80px;
      padding-bottom: 80px;
    }
  }

  .i-hairline {
    border-top: 1px solid var(--p-hairline);
  }

  .i-scroller {
    background: linear-gradient(to right, var(--paper) 30%, #fbf8f200) left center / 44px 100% no-repeat local, linear-gradient(to left, var(--paper) 30%, #fbf8f200) right center / 44px 100% no-repeat local, radial-gradient(farthest-side at 0 50%, #211d1529, #211d1500) left center / 14px 100% no-repeat scroll, radial-gradient(farthest-side at 100% 50%, #211d1529, #211d1500) right center / 14px 100% no-repeat scroll;
  }

  .i-sheet {
    background: var(--paper-raised);
    border: 1px solid var(--color-ink-200);
    border-radius: 10px;
  }

  .instrument-site .ico {
    stroke: currentColor;
    fill: none;
    stroke-width: 1.5px;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex: none;
    width: 15px;
    height: 15px;
  }

  .instrument-site [data-tip] {
    position: relative;
  }

  .instrument-site [data-tip]:after {
    content: attr(data-tip);
    background: var(--frame);
    color: #e7e4ee;
    font-family: var(--font-sans);
    letter-spacing: 0;
    text-transform: none;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    z-index: 40;
    border-radius: 6px;
    padding: 5px 9px;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.3;
    transition: opacity .12s ease-out .3s;
    position: absolute;
    bottom: calc(100% + 9px);
    left: 50%;
    transform: translateX(-50%);
  }

  .instrument-site [data-tip]:hover:after, .instrument-site [data-tip]:focus-visible:after {
    opacity: 1;
  }

  .instrument-site [data-tip].tip-below:after {
    top: calc(100% + 9px);
    bottom: auto;
  }

  .instrument-site [data-tip].tip-left:after {
    left: auto;
    right: 0;
    transform: none;
  }

  .i-verb {
    font-family: var(--font-sans);
    color: #f0eef4;
    background: var(--frame);
    border: 1px solid var(--frame);
    cursor: pointer;
    border-radius: 7px;
    align-items: center;
    min-height: 44px;
    padding: 10px 18px;
    font-size: 13.5px;
    font-weight: 600;
    transition: background-color .16s ease-out;
    display: inline-flex;
  }

  .i-verb:hover {
    background: var(--frame-2);
    color: #fff;
  }

  .i-aside {
    font-family: var(--font-sans);
    color: var(--p-ink-2);
    text-decoration: underline;
    -webkit-text-decoration-color: var(--p-hairline);
    -webkit-text-decoration-color: var(--p-hairline);
    text-decoration-color: var(--p-hairline);
    text-underline-offset: 4px;
    align-items: center;
    min-height: 44px;
    font-size: 13.5px;
    transition: color .16s ease-out, text-decoration-color .16s ease-out;
    display: inline-flex;
  }

  .i-aside:hover {
    color: var(--p-ink);
    -webkit-text-decoration-color: var(--beam);
    -webkit-text-decoration-color: var(--beam);
    text-decoration-color: var(--beam);
  }

  .instrument-site :focus-visible {
    outline: 2px solid var(--beam);
    outline-offset: 2px;
  }

  .i-mark-stop {
    text-underline-offset: 4px;
    text-decoration-line: underline;
    text-decoration-style: wavy;
    text-decoration-thickness: 1px;
    -webkit-text-decoration-color: var(--flag);
    -webkit-text-decoration-color: var(--flag);
    text-decoration-color: var(--flag);
  }

  .i-mark-hold {
    text-underline-offset: 4px;
    text-decoration-line: underline;
    text-decoration-style: wavy;
    text-decoration-thickness: 1px;
    -webkit-text-decoration-color: var(--flag-soft);
    -webkit-text-decoration-color: var(--flag-soft);
    text-decoration-color: var(--flag-soft);
  }

  .i-plate {
    background: var(--frame);
    color: var(--readout);
  }

  .i-plate a, .i-plate button {
    color: var(--readout);
  }

  .i-plate a:hover, .i-plate button:hover {
    color: var(--readout-hi);
  }

  .i-plate :focus-visible {
    outline: 2px solid var(--beam-frame);
    outline-offset: 2px;
  }

  .i-plate-btn {
    color: var(--readout);
    cursor: pointer;
    background: none;
    border: 0;
    border-radius: 6px;
    place-items: center;
    min-width: 30px;
    min-height: 30px;
    padding: 0;
    display: grid;
  }

  .i-plate-btn:hover {
    background: var(--frame-2);
    color: var(--readout-hi);
  }

  .i-plate-verb {
    font-family: var(--font-sans);
    color: var(--readout-hi);
    border: 1px solid var(--frame-line);
    background: none;
    border-radius: 7px;
    align-items: center;
    min-height: 40px;
    padding: 8px 16px;
    font-size: 13.5px;
    font-weight: 600;
    transition: background-color .16s ease-out, border-color .16s ease-out;
    display: inline-flex;
  }

  .i-plate-verb:hover {
    background: var(--frame-2);
    border-color: var(--readout-dim);
    color: var(--readout-hi);
  }

  .app-scope[data-scope="account"] {
    background: #161d23;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .app-scope[data-scope="account"] {
      background: color-mix(in oklab, var(--color-ink-050) 96%, var(--color-beam) 4%);
    }
  }

  .app-scope[data-scope="brand"] {
    background: var(--color-ink-000);
  }

  .copy-paper {
    cursor: var(--cursor-write), text;
  }

  .copy-prose {
    max-width: 66ch;
  }

  .copy-block {
    position: relative;
  }

  .copy-block + .copy-block {
    margin-top: 44px;
  }

  .copy-para {
    white-space: pre-wrap;
    color: var(--color-ink-900);
    outline: none;
    margin: 0;
    font-size: 17px;
    line-height: 31px;
  }

  .copy-para[data-placeholder]:empty:before {
    content: attr(data-placeholder);
    color: var(--color-ink-400);
    pointer-events: none;
  }

  .copy-para:focus-visible {
    box-shadow: -15px 0 0 -12px var(--color-beam);
    outline: none !important;
  }

  .copy-block-tag {
    text-align: right;
    white-space: nowrap;
    text-overflow: ellipsis;
    opacity: 0;
    pointer-events: none;
    width: 106px;
    transition: opacity .12s;
    position: absolute;
    top: 10px;
    left: -132px;
    overflow: hidden;
  }

  .copy-block:hover .copy-block-tag, .copy-block:focus-within .copy-block-tag {
    opacity: 1;
  }

  .copy-block-notes {
    border-left: 2px solid var(--color-ink-200);
    margin-top: 52px;
    padding-left: 18px;
  }

  .copy-block-notes .copy-para {
    color: var(--color-ink-400);
    font-size: 15px;
    line-height: 26px;
  }

  .copy-block[data-reach="on"]:after {
    content: "";
    background: var(--gradient-dichroic);
    border-radius: 2px;
    width: 2px;
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: -26px;
  }

  .copy-block-notes[data-reach="on"]:after {
    background: var(--color-ink-200);
    width: 1px;
  }

  .mark-decided {
    color: inherit;
    -webkit-text-decoration: underline wavy var(--color-flag);
    -webkit-text-decoration: underline wavy var(--color-flag);
    text-decoration: underline wavy var(--color-flag);
    text-underline-offset: 5px;
    cursor: pointer;
    background: none;
    text-decoration-thickness: 1.5px;
  }

  .mark-judge {
    color: inherit;
    border-left: 1.5px solid var(--color-beam);
    border-right: 1.5px solid var(--color-beam);
    cursor: pointer;
    background: none;
    padding: 0 3px;
  }

  .mark-cite {
    font-family: var(--font-mono);
    vertical-align: super;
    color: var(--color-ink-400);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    padding: 0 1px;
    font-size: 9px;
  }

  .mark-cite:hover {
    color: var(--color-beam);
  }

  @keyframes copy-landed {
    0% {
      background: var(--color-beam-dim);
    }

    100% {
      background: none;
    }
  }

  .copy-block-changed {
    border-radius: 6px;
    animation: 1.4s ease-out copy-landed;
  }

  @media (prefers-reduced-motion: reduce) {
    .copy-block-changed {
      animation: none;
    }
  }

  .copy-work {
    grid-template-columns: minmax(var(--doc-min), 1fr) var(--outline-w, 0px);
    grid-template-rows: minmax(0, 1fr) 5px var(--agent-h, 320px);
    flex: 1;
    min-height: 0;
    display: grid;
  }

  .copy-work .copy-doc-pane {
    grid-area: 1 / 1;
  }

  .copy-work .copy-outline {
    grid-area: 1 / 2;
  }

  .copy-work .copy-divider {
    grid-area: 2 / 1 / auto / -1;
  }

  .copy-work .copy-agent {
    grid-area: 3 / 1 / auto / -1;
  }

  .copy-work {
    --doc-min: min(20rem, 100%);
  }

  .copy-doc-pane {
    min-width: var(--doc-min, min(20rem, 100%));
  }

  .copy-doc-pane, .copy-agent {
    flex-direction: column;
    min-height: 0;
    display: flex;
  }

  .copy-agent {
    border-top: 1px solid var(--color-ink-200);
    min-width: 0;
  }

  .copy-outline {
    border-left: 1px solid var(--color-ink-200);
  }

  .copy-work[data-outline="open"] {
    --outline-w: 236px;
  }

  .copy-work[data-agent="closed"] {
    --agent-w: 0px;
    --agent-h: 0px;
  }

  @media not all and (min-width: 48rem) {
    .copy-work {
      grid-template-rows: minmax(0, 1fr);
      grid-template-columns: minmax(0, 1fr);
    }

    .copy-work .copy-doc-pane, .copy-work .copy-outline, .copy-work .copy-agent {
      grid-area: 1 / 1;
    }

    .copy-work .copy-divider, .copy-work[data-pane="document"] .copy-outline, .copy-work[data-pane="document"] .copy-agent, .copy-work[data-pane="outline"] .copy-doc-pane, .copy-work[data-pane="outline"] .copy-agent, .copy-work[data-pane="agent"] .copy-doc-pane, .copy-work[data-pane="agent"] .copy-outline {
      display: none;
    }

    .copy-work .copy-agent {
      border-top: 0;
    }

    .copy-work .copy-outline {
      border-left: 0;
    }

    .copy-work[data-outline="open"] {
      --outline-w: auto;
    }
  }

  @media (min-width: 64rem) {
    .copy-work[data-dock="right"] {
      grid-template-columns: minmax(var(--doc-min), 1fr) 5px var(--outline-w, 0px) minmax(0, var(--agent-w, 440px));
      grid-template-rows: minmax(0, 1fr);
    }

    .copy-work[data-dock="right"] .copy-doc-pane {
      grid-area: 1 / 1;
    }

    .copy-work[data-dock="right"] .copy-divider {
      grid-area: 1 / 2;
    }

    .copy-work[data-dock="right"] .copy-outline {
      grid-area: 1 / 3;
    }

    .copy-work[data-dock="right"] .copy-agent {
      border-top: 0;
      border-left: 1px solid var(--color-ink-200);
      grid-area: 1 / 4;
    }
  }

  .copy-divider {
    background: var(--color-ink-200);
    cursor: row-resize;
    border: 0;
    padding: 0;
    transition: background-color .12s;
    position: relative;
  }

  .copy-divider:before {
    content: "";
    position: absolute;
    inset: -4px 0;
  }

  .copy-divider:after {
    content: "";
    background: var(--color-ink-400);
    opacity: .55;
    border-radius: 3px;
    width: 26px;
    height: 3px;
    transition: opacity .12s, background-color .12s;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  @media (min-width: 64rem) {
    .copy-work[data-dock="right"] .copy-divider {
      cursor: col-resize;
    }

    .copy-work[data-dock="right"] .copy-divider:before {
      inset: 0 -4px;
    }

    .copy-work[data-dock="right"] .copy-divider:after {
      width: 3px;
      height: 26px;
    }
  }

  .copy-divider:hover:after, .copy-divider:focus-visible:after {
    opacity: 1;
    background: var(--color-beam);
  }

  .copy-divider:hover, .copy-divider:focus-visible {
    background: var(--color-beam);
  }

  .lightwell {
    overflow-x: clip;
  }

  .lightwell:before {
    content: "";
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(46% 40% at 28% 24%, #ff2e8e12, #0000 64%), radial-gradient(46% 40% at 74% 74%, #22e0d50f, #0000 64%), radial-gradient(#ffffff1a 0%, #0000 68%);
    position: absolute;
    inset: -14%;
  }

  .shaft {
    z-index: 0;
    pointer-events: none;
    position: absolute;
    inset: 0;
    overflow: hidden;
  }

  .shaft:before, .shaft:after {
    content: "";
    background: var(--gradient-dichroic);
    height: 180%;
    position: absolute;
    top: -40%;
    transform: rotate(14deg);
  }

  .shaft:before {
    filter: blur(56px);
    opacity: .46;
    width: 26vw;
    max-width: 380px;
    right: -10%;
  }

  .shaft:after {
    opacity: .8;
    width: 5px;
    right: 26%;
  }

  @media not all and (min-width: 64rem) {
    .shaft:before {
      opacity: .32;
      right: -22%;
    }

    .shaft:after {
      display: none;
    }
  }

  .spectrum-rule {
    background: var(--gradient-dichroic);
    height: 2px;
  }

  [data-lights="dim"] .chrome {
    opacity: .12;
    transition: opacity .22s;
  }

  [data-lights="dim"] .chrome:hover, [data-lights="dim"] .chrome:focus-within {
    opacity: 1;
  }

  [data-lights="out"] .chrome {
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s;
  }

  [data-lights="out"] .chrome:focus-within {
    opacity: 1;
    pointer-events: auto;
  }

  [data-lights="out"] .lightwell:before {
    opacity: 0;
  }

  @keyframes develop {
    from {
      opacity: 0;
      filter: grayscale() brightness(1.6) contrast(.5);
    }

    to {
      opacity: 1;
      filter: none;
    }
  }

  .develop {
    animation: .52s ease-out backwards develop;
  }

  @keyframes latent {
    0%, 100% {
      background-color: var(--color-ink-050);
    }

    50% {
      background-color: var(--color-ink-100);
    }
  }

  .latent {
    animation: 1.6s ease-in-out infinite backwards latent;
  }

  .mark {
    text-decoration-line: underline;
    -webkit-text-decoration-color: var(--color-beam);
    -webkit-text-decoration-color: var(--color-beam);
    text-decoration-color: var(--color-beam);
    text-underline-offset: 4px;
    text-decoration-thickness: 2px;
    transition: text-decoration-thickness .12s, text-underline-offset .12s, color .12s;
  }

  .mark:hover, .mark:focus-visible {
    text-underline-offset: 3px;
    text-decoration-thickness: 3px;
  }

  @media (prefers-reduced-motion: reduce) {
    .mark {
      transition: none;
    }

    .develop {
      animation: none;
    }

    .latent {
      background-color: var(--color-ink-050);
      animation: none;
    }
  }

  .panel {
    background: var(--color-ink-050);
    border: 1px solid var(--color-ink-200);
    border-radius: var(--radius-panel);
  }

  .tech {
    font-family: var(--font-mono);
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
    color: var(--color-ink-500);
    font-size: 12px;
    line-height: 16px;
  }

  .micro {
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--color-ink-400);
    font-size: 11px;
    font-weight: 600;
    line-height: 16px;
  }

  .safe-shell {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }

  .edge-cue {
    position: relative;
    overflow-x: clip;
  }

  .edge-cue:before, .edge-cue:after {
    content: "";
    z-index: 1;
    pointer-events: none;
    opacity: 0;
    width: 32px;
    transition: opacity .15s ease-out;
    position: absolute;
    top: 0;
    bottom: 0;
  }

  .edge-cue:before {
    background: linear-gradient(to right, var(--color-ink-000), transparent);
    left: 0;
  }

  .edge-cue:after {
    background: linear-gradient(to left, var(--color-ink-000), transparent);
    right: 0;
  }

  .edge-cue[data-cue-start="true"]:before, .edge-cue[data-cue-end="true"]:after {
    opacity: 1;
  }

  .panel-scroll summary {
    z-index: 2;
    background: var(--color-ink-050);
    position: sticky;
    top: 0;
  }
}

@layer utilities {
  .\@container {
    container-type: inline-size;
  }

  .pointer-events-auto {
    pointer-events: auto;
  }

  .pointer-events-none {
    pointer-events: none;
  }

  .collapse {
    visibility: collapse;
  }

  .invisible {
    visibility: hidden;
  }

  .visible {
    visibility: visible;
  }

  .visible\! {
    visibility: visible !important;
  }

  .sr-only {
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    position: absolute;
    overflow: hidden;
  }

  .absolute {
    position: absolute;
  }

  .fixed {
    position: fixed;
  }

  .relative {
    position: relative;
  }

  .static {
    position: static;
  }

  .sticky {
    position: sticky;
  }

  .inset-0 {
    inset: 0;
  }

  .inset-px {
    inset: 1px;
  }

  .inset-x-0 {
    inset-inline: 0;
  }

  .inset-y-0 {
    inset-block: 0;
  }

  .inset-y-1 {
    inset-block: var(--spacing);
  }

  .-top-0 {
    top: 0;
  }

  .-top-1 {
    top: calc(var(--spacing) * -1);
  }

  .top-0 {
    top: 0;
  }

  .top-1 {
    top: var(--spacing);
  }

  .top-1\/2 {
    top: 50%;
  }

  .top-3 {
    top: calc(var(--spacing) * 3);
  }

  .top-3\.5 {
    top: calc(var(--spacing) * 3.5);
  }

  .top-6 {
    top: calc(var(--spacing) * 6);
  }

  .top-8 {
    top: calc(var(--spacing) * 8);
  }

  .top-\[calc\(var\(--bar\)\+8px\)\] {
    top: calc(var(--bar) + 8px);
  }

  .top-\[max\(8px\,calc\(var\(--bar\)-2px\)\)\] {
    top: max(8px, calc(var(--bar) - 2px));
  }

  .top-full {
    top: 100%;
  }

  .top-px {
    top: 1px;
  }

  .-right-0, .right-0 {
    right: 0;
  }

  .right-1 {
    right: var(--spacing);
  }

  .right-1\/4 {
    right: 25%;
  }

  .right-\[6\%\] {
    right: 6%;
  }

  .right-\[12px\] {
    right: 12px;
  }

  .right-px {
    right: 1px;
  }

  .bottom-0 {
    bottom: 0;
  }

  .bottom-4 {
    bottom: calc(var(--spacing) * 4);
  }

  .bottom-full {
    bottom: 100%;
  }

  .left-0 {
    left: 0;
  }

  .left-1 {
    left: var(--spacing);
  }

  .left-1\/2 {
    left: 50%;
  }

  .left-1\/4 {
    left: 25%;
  }

  .left-3 {
    left: calc(var(--spacing) * 3);
  }

  .left-\[6\%\] {
    left: 6%;
  }

  .left-\[6\.5px\] {
    left: 6.5px;
  }

  .isolate {
    isolation: isolate;
  }

  .-z-10 {
    z-index: calc(10 * -1);
  }

  .-z-\[1\] {
    z-index: calc(1 * -1);
  }

  .z-0 {
    z-index: 0;
  }

  .z-10 {
    z-index: 10;
  }

  .z-20 {
    z-index: 20;
  }

  .z-30 {
    z-index: 30;
  }

  .z-40 {
    z-index: 40;
  }

  .z-50 {
    z-index: 50;
  }

  .z-60, .z-\[60\] {
    z-index: 60;
  }

  .z-\[100\] {
    z-index: 100;
  }

  .z-auto {
    z-index: auto;
  }

  .col-1 {
    grid-column: 1;
  }

  .col-span-full {
    grid-column: 1 / -1;
  }

  .row-1 {
    grid-row: 1;
  }

  .row-span-full {
    grid-row: 1 / -1;
  }

  .float-left {
    float: left;
  }

  .container {
    width: 100%;
  }

  @media (min-width: 40rem) {
    .container {
      max-width: 40rem;
    }
  }

  @media (min-width: 48rem) {
    .container {
      max-width: 48rem;
    }
  }

  @media (min-width: 64rem) {
    .container {
      max-width: 64rem;
    }
  }

  @media (min-width: 80rem) {
    .container {
      max-width: 80rem;
    }
  }

  @media (min-width: 96rem) {
    .container {
      max-width: 96rem;
    }
  }

  .-m-1 {
    margin: calc(var(--spacing) * -1);
  }

  .m-0 {
    margin: 0;
  }

  .m-1 {
    margin: var(--spacing);
  }

  .m-2 {
    margin: calc(var(--spacing) * 2);
  }

  .m-3 {
    margin: calc(var(--spacing) * 3);
  }

  .m-4 {
    margin: calc(var(--spacing) * 4);
  }

  .m-5 {
    margin: calc(var(--spacing) * 5);
  }

  .m-auto {
    margin: auto;
  }

  .-mx-1 {
    margin-inline: calc(var(--spacing) * -1);
  }

  .-mx-4 {
    margin-inline: calc(var(--spacing) * -4);
  }

  .-mx-6 {
    margin-inline: calc(var(--spacing) * -6);
  }

  .mx-1 {
    margin-inline: var(--spacing);
  }

  .mx-2 {
    margin-inline: calc(var(--spacing) * 2);
  }

  .mx-3 {
    margin-inline: calc(var(--spacing) * 3);
  }

  .mx-4 {
    margin-inline: calc(var(--spacing) * 4);
  }

  .mx-5 {
    margin-inline: calc(var(--spacing) * 5);
  }

  .mx-auto {
    margin-inline: auto;
  }

  .-my-1 {
    margin-block: calc(var(--spacing) * -1);
  }

  .my-1 {
    margin-block: var(--spacing);
  }

  .my-2 {
    margin-block: calc(var(--spacing) * 2);
  }

  .my-3 {
    margin-block: calc(var(--spacing) * 3);
  }

  .my-4 {
    margin-block: calc(var(--spacing) * 4);
  }

  .my-5 {
    margin-block: calc(var(--spacing) * 5);
  }

  .-ms-1 {
    margin-inline-start: calc(var(--spacing) * -1);
  }

  .-me-1 {
    margin-inline-end: calc(var(--spacing) * -1);
  }

  .-mt-0 {
    margin-top: 0;
  }

  .-mt-1 {
    margin-top: calc(var(--spacing) * -1);
  }

  .mt-0 {
    margin-top: 0;
  }

  .mt-0\.5 {
    margin-top: calc(var(--spacing) * .5);
  }

  .mt-1 {
    margin-top: var(--spacing);
  }

  .mt-1\.5 {
    margin-top: calc(var(--spacing) * 1.5);
  }

  .mt-2 {
    margin-top: calc(var(--spacing) * 2);
  }

  .mt-2\.5 {
    margin-top: calc(var(--spacing) * 2.5);
  }

  .mt-3 {
    margin-top: calc(var(--spacing) * 3);
  }

  .mt-3\.5 {
    margin-top: calc(var(--spacing) * 3.5);
  }

  .mt-4 {
    margin-top: calc(var(--spacing) * 4);
  }

  .mt-5 {
    margin-top: calc(var(--spacing) * 5);
  }

  .mt-6 {
    margin-top: calc(var(--spacing) * 6);
  }

  .mt-7 {
    margin-top: calc(var(--spacing) * 7);
  }

  .mt-8 {
    margin-top: calc(var(--spacing) * 8);
  }

  .mt-9 {
    margin-top: calc(var(--spacing) * 9);
  }

  .mt-10 {
    margin-top: calc(var(--spacing) * 10);
  }

  .mt-12 {
    margin-top: calc(var(--spacing) * 12);
  }

  .mt-14 {
    margin-top: calc(var(--spacing) * 14);
  }

  .mt-16 {
    margin-top: calc(var(--spacing) * 16);
  }

  .mt-\[0\.4em\] {
    margin-top: .4em;
  }

  .mt-\[3px\] {
    margin-top: 3px;
  }

  .mt-\[5cqw\] {
    margin-top: 5cqw;
  }

  .mt-auto {
    margin-top: auto;
  }

  .mt-px {
    margin-top: 1px;
  }

  .-mr-1 {
    margin-right: calc(var(--spacing) * -1);
  }

  .mr-0 {
    margin-right: 0;
  }

  .mr-0\.5 {
    margin-right: calc(var(--spacing) * .5);
  }

  .mr-1 {
    margin-right: var(--spacing);
  }

  .mr-1\.5 {
    margin-right: calc(var(--spacing) * 1.5);
  }

  .mr-2 {
    margin-right: calc(var(--spacing) * 2);
  }

  .mr-2\.5 {
    margin-right: calc(var(--spacing) * 2.5);
  }

  .mr-3 {
    margin-right: calc(var(--spacing) * 3);
  }

  .mr-4 {
    margin-right: calc(var(--spacing) * 4);
  }

  .mr-5 {
    margin-right: calc(var(--spacing) * 5);
  }

  .mb-1 {
    margin-bottom: var(--spacing);
  }

  .mb-1\.5 {
    margin-bottom: calc(var(--spacing) * 1.5);
  }

  .mb-2 {
    margin-bottom: calc(var(--spacing) * 2);
  }

  .mb-2\.5 {
    margin-bottom: calc(var(--spacing) * 2.5);
  }

  .mb-3 {
    margin-bottom: calc(var(--spacing) * 3);
  }

  .mb-4 {
    margin-bottom: calc(var(--spacing) * 4);
  }

  .mb-5 {
    margin-bottom: calc(var(--spacing) * 5);
  }

  .mb-6 {
    margin-bottom: calc(var(--spacing) * 6);
  }

  .mb-8 {
    margin-bottom: calc(var(--spacing) * 8);
  }

  .mb-9 {
    margin-bottom: calc(var(--spacing) * 9);
  }

  .mb-10 {
    margin-bottom: calc(var(--spacing) * 10);
  }

  .-ml-0 {
    margin-left: 0;
  }

  .-ml-1 {
    margin-left: calc(var(--spacing) * -1);
  }

  .-ml-2\.5 {
    margin-left: calc(var(--spacing) * -2.5);
  }

  .-ml-px {
    margin-left: -1px;
  }

  .ml-0 {
    margin-left: 0;
  }

  .ml-0\.5 {
    margin-left: calc(var(--spacing) * .5);
  }

  .ml-1 {
    margin-left: var(--spacing);
  }

  .ml-2 {
    margin-left: calc(var(--spacing) * 2);
  }

  .ml-3 {
    margin-left: calc(var(--spacing) * 3);
  }

  .ml-4 {
    margin-left: calc(var(--spacing) * 4);
  }

  .ml-5 {
    margin-left: calc(var(--spacing) * 5);
  }

  .ml-\[2px\] {
    margin-left: 2px;
  }

  .ml-auto {
    margin-left: auto;
  }

  .line-clamp-4 {
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    display: -webkit-box;
    overflow: hidden;
  }

  .block {
    display: block;
  }

  .contents {
    display: contents;
  }

  .contents\! {
    display: contents !important;
  }

  .flex {
    display: flex;
  }

  .grid {
    display: grid;
  }

  .hidden {
    display: none;
  }

  .inline {
    display: inline;
  }

  .inline-block {
    display: inline-block;
  }

  .inline-flex {
    display: inline-flex;
  }

  .list-item {
    display: list-item;
  }

  .table {
    display: table;
  }

  .table-cell {
    display: table-cell;
  }

  .table-row {
    display: table-row;
  }

  .aspect-\[4\/5\] {
    aspect-ratio: 4 / 5;
  }

  .aspect-square {
    aspect-ratio: 1;
  }

  .size-2 {
    width: calc(var(--spacing) * 2);
    height: calc(var(--spacing) * 2);
  }

  .size-5 {
    width: calc(var(--spacing) * 5);
    height: calc(var(--spacing) * 5);
  }

  .size-6 {
    width: calc(var(--spacing) * 6);
    height: calc(var(--spacing) * 6);
  }

  .size-7 {
    width: calc(var(--spacing) * 7);
    height: calc(var(--spacing) * 7);
  }

  .size-8 {
    width: calc(var(--spacing) * 8);
    height: calc(var(--spacing) * 8);
  }

  .size-24 {
    width: calc(var(--spacing) * 24);
    height: calc(var(--spacing) * 24);
  }

  .size-\[var\(--cds-avatar-sm\)\] {
    width: var(--cds-avatar-sm);
    height: var(--cds-avatar-sm);
  }

  .size-full {
    width: 100%;
    height: 100%;
  }

  .h-0\.5 {
    height: calc(var(--spacing) * .5);
  }

  .h-1 {
    height: var(--spacing);
  }

  .h-1\.5 {
    height: calc(var(--spacing) * 1.5);
  }

  .h-2 {
    height: calc(var(--spacing) * 2);
  }

  .h-2\.5 {
    height: calc(var(--spacing) * 2.5);
  }

  .h-3 {
    height: calc(var(--spacing) * 3);
  }

  .h-3\.5 {
    height: calc(var(--spacing) * 3.5);
  }

  .h-4 {
    height: calc(var(--spacing) * 4);
  }

  .h-5 {
    height: calc(var(--spacing) * 5);
  }

  .h-6 {
    height: calc(var(--spacing) * 6);
  }

  .h-7 {
    height: calc(var(--spacing) * 7);
  }

  .h-8 {
    height: calc(var(--spacing) * 8);
  }

  .h-9 {
    height: calc(var(--spacing) * 9);
  }

  .h-10 {
    height: calc(var(--spacing) * 10);
  }

  .h-11 {
    height: calc(var(--spacing) * 11);
  }

  .h-14 {
    height: calc(var(--spacing) * 14);
  }

  .h-16 {
    height: calc(var(--spacing) * 16);
  }

  .h-24 {
    height: calc(var(--spacing) * 24);
  }

  .h-28 {
    height: calc(var(--spacing) * 28);
  }

  .h-32 {
    height: calc(var(--spacing) * 32);
  }

  .h-40 {
    height: calc(var(--spacing) * 40);
  }

  .h-48 {
    height: calc(var(--spacing) * 48);
  }

  .h-60 {
    height: calc(var(--spacing) * 60);
  }

  .h-\[1\.1em\] {
    height: 1.1em;
  }

  .h-\[1\.3rem\] {
    height: 1.3rem;
  }

  .h-\[1\.05em\] {
    height: 1.05em;
  }

  .h-\[1\.5px\] {
    height: 1.5px;
  }

  .h-\[2\.6rem\] {
    height: 2.6rem;
  }

  .h-\[2px\] {
    height: 2px;
  }

  .h-\[3\.4rem\] {
    height: 3.4rem;
  }

  .h-\[3px\] {
    height: 3px;
  }

  .h-\[3rem\] {
    height: 3rem;
  }

  .h-\[5px\] {
    height: 5px;
  }

  .h-\[6\.5rem\] {
    height: 6.5rem;
  }

  .h-\[7\.5rem\] {
    height: 7.5rem;
  }

  .h-\[14px\] {
    height: 14px;
  }

  .h-\[18px\] {
    height: 18px;
  }

  .h-\[84px\] {
    height: 84px;
  }

  .h-\[88dvh\] {
    height: 88dvh;
  }

  .h-auto {
    height: auto;
  }

  .h-dvh {
    height: 100dvh;
  }

  .h-full {
    height: 100%;
  }

  .h-px {
    height: 1px;
  }

  .max-h-24 {
    max-height: calc(var(--spacing) * 24);
  }

  .max-h-56 {
    max-height: calc(var(--spacing) * 56);
  }

  .max-h-64 {
    max-height: calc(var(--spacing) * 64);
  }

  .max-h-72 {
    max-height: calc(var(--spacing) * 72);
  }

  .max-h-80 {
    max-height: calc(var(--spacing) * 80);
  }

  .max-h-\[60vh\] {
    max-height: 60vh;
  }

  .max-h-\[85dvh\] {
    max-height: 85dvh;
  }

  .max-h-\[88dvh\] {
    max-height: 88dvh;
  }

  .max-h-\[calc\(100dvh-4rem\)\] {
    max-height: calc(100dvh - 4rem);
  }

  .max-h-\[min\(720px\,calc\(100dvh-2rem\)\)\] {
    max-height: min(720px, 100dvh - 2rem);
  }

  .min-h-0 {
    min-height: 0;
  }

  .min-h-6 {
    min-height: calc(var(--spacing) * 6);
  }

  .min-h-8 {
    min-height: calc(var(--spacing) * 8);
  }

  .min-h-9 {
    min-height: calc(var(--spacing) * 9);
  }

  .min-h-11 {
    min-height: calc(var(--spacing) * 11);
  }

  .min-h-16 {
    min-height: calc(var(--spacing) * 16);
  }

  .min-h-\[2\.6rem\] {
    min-height: 2.6rem;
  }

  .min-h-\[2\.25rem\] {
    min-height: 2.25rem;
  }

  .min-h-\[2\.75rem\] {
    min-height: 2.75rem;
  }

  .min-h-\[3\.2rem\] {
    min-height: 3.2rem;
  }

  .min-h-\[3\.5rem\] {
    min-height: 3.5rem;
  }

  .min-h-\[6\.5rem\] {
    min-height: 6.5rem;
  }

  .min-h-\[44px\] {
    min-height: 44px;
  }

  .min-h-\[64px\] {
    min-height: 64px;
  }

  .min-h-\[72px\] {
    min-height: 72px;
  }

  .min-h-\[88px\] {
    min-height: 88px;
  }

  .min-h-\[104px\] {
    min-height: 104px;
  }

  .min-h-dvh {
    min-height: 100dvh;
  }

  .min-h-full {
    min-height: 100%;
  }

  .w-0 {
    width: 0;
  }

  .w-1 {
    width: var(--spacing);
  }

  .w-1\.5 {
    width: calc(var(--spacing) * 1.5);
  }

  .w-1\/2 {
    width: 50%;
  }

  .w-1\/3 {
    width: 33.3333%;
  }

  .w-2 {
    width: calc(var(--spacing) * 2);
  }

  .w-2\.5 {
    width: calc(var(--spacing) * 2.5);
  }

  .w-2\/3 {
    width: 66.6667%;
  }

  .w-3 {
    width: calc(var(--spacing) * 3);
  }

  .w-4 {
    width: calc(var(--spacing) * 4);
  }

  .w-5 {
    width: calc(var(--spacing) * 5);
  }

  .w-6 {
    width: calc(var(--spacing) * 6);
  }

  .w-7 {
    width: calc(var(--spacing) * 7);
  }

  .w-8 {
    width: calc(var(--spacing) * 8);
  }

  .w-10 {
    width: calc(var(--spacing) * 10);
  }

  .w-11 {
    width: calc(var(--spacing) * 11);
  }

  .w-16 {
    width: calc(var(--spacing) * 16);
  }

  .w-20 {
    width: calc(var(--spacing) * 20);
  }

  .w-24 {
    width: calc(var(--spacing) * 24);
  }

  .w-32 {
    width: calc(var(--spacing) * 32);
  }

  .w-36 {
    width: calc(var(--spacing) * 36);
  }

  .w-56 {
    width: calc(var(--spacing) * 56);
  }

  .w-64 {
    width: calc(var(--spacing) * 64);
  }

  .w-80 {
    width: calc(var(--spacing) * 80);
  }

  .w-84 {
    width: calc(var(--spacing) * 84);
  }

  .w-100 {
    width: calc(var(--spacing) * 100);
  }

  .w-\[2px\] {
    width: 2px;
  }

  .w-\[3px\] {
    width: 3px;
  }

  .w-\[13\.5rem\] {
    width: 13.5rem;
  }

  .w-\[50\%\] {
    width: 50%;
  }

  .w-\[110px\] {
    width: 110px;
  }

  .w-\[130px\] {
    width: 130px;
  }

  .w-\[140px\] {
    width: 140px;
  }

  .w-\[150px\] {
    width: 150px;
  }

  .w-\[170px\] {
    width: 170px;
  }

  .w-\[268px\] {
    width: 268px;
  }

  .w-\[320px\] {
    width: 320px;
  }

  .w-\[336px\] {
    width: 336px;
  }

  .w-\[calc\(50\%-0\.25rem\)\] {
    width: calc(50% - .25rem);
  }

  .w-\[calc\(50\%-16px\)\] {
    width: calc(50% - 16px);
  }

  .w-\[min\(340px\,70vw\)\] {
    width: min(340px, 70vw);
  }

  .w-\[min\(620px\,94vw\)\] {
    width: min(620px, 94vw);
  }

  .w-\[min\(980px\,94vw\)\] {
    width: min(980px, 94vw);
  }

  .w-auto {
    width: auto;
  }

  .w-fit {
    width: fit-content;
  }

  .w-full {
    width: 100%;
  }

  .w-px {
    width: 1px;
  }

  .max-w-2xl {
    max-width: var(--container-2xl);
  }

  .max-w-3xl {
    max-width: var(--container-3xl);
  }

  .max-w-\[13rem\] {
    max-width: 13rem;
  }

  .max-w-\[16ch\] {
    max-width: 16ch;
  }

  .max-w-\[19rem\] {
    max-width: 19rem;
  }

  .max-w-\[20ch\] {
    max-width: 20ch;
  }

  .max-w-\[22ch\] {
    max-width: 22ch;
  }

  .max-w-\[24ch\] {
    max-width: 24ch;
  }

  .max-w-\[30ch\] {
    max-width: 30ch;
  }

  .max-w-\[34ch\] {
    max-width: 34ch;
  }

  .max-w-\[42ch\] {
    max-width: 42ch;
  }

  .max-w-\[44ch\] {
    max-width: 44ch;
  }

  .max-w-\[46ch\] {
    max-width: 46ch;
  }

  .max-w-\[48ch\] {
    max-width: 48ch;
  }

  .max-w-\[52ch\] {
    max-width: 52ch;
  }

  .max-w-\[54ch\] {
    max-width: 54ch;
  }

  .max-w-\[60ch\] {
    max-width: 60ch;
  }

  .max-w-\[62ch\] {
    max-width: 62ch;
  }

  .max-w-\[70ch\] {
    max-width: 70ch;
  }

  .max-w-\[76ch\] {
    max-width: 76ch;
  }

  .max-w-\[190px\] {
    max-width: 190px;
  }

  .max-w-\[280px\] {
    max-width: 280px;
  }

  .max-w-\[390px\] {
    max-width: 390px;
  }

  .max-w-\[420px\] {
    max-width: 420px;
  }

  .max-w-\[440px\] {
    max-width: 440px;
  }

  .max-w-\[460px\] {
    max-width: 460px;
  }

  .max-w-\[520px\] {
    max-width: 520px;
  }

  .max-w-\[560px\] {
    max-width: 560px;
  }

  .max-w-\[620px\] {
    max-width: 620px;
  }

  .max-w-\[640px\] {
    max-width: 640px;
  }

  .max-w-\[672px\] {
    max-width: 672px;
  }

  .max-w-\[720px\] {
    max-width: 720px;
  }

  .max-w-\[820px\] {
    max-width: 820px;
  }

  .max-w-\[880px\] {
    max-width: 880px;
  }

  .max-w-\[900px\] {
    max-width: 900px;
  }

  .max-w-\[960px\] {
    max-width: 960px;
  }

  .max-w-\[1120px\] {
    max-width: 1120px;
  }

  .max-w-\[1180px\] {
    max-width: 1180px;
  }

  .max-w-\[Npx\] {
    max-width: Npx;
  }

  .max-w-\[min\(280px\,calc\(100vw-24px\)\)\] {
    max-width: min(280px, 100vw - 24px);
  }

  .max-w-full {
    max-width: 100%;
  }

  .max-w-lg {
    max-width: var(--container-lg);
  }

  .max-w-md {
    max-width: var(--container-md);
  }

  .max-w-none {
    max-width: none;
  }

  .max-w-xl {
    max-width: var(--container-xl);
  }

  .max-w-xs {
    max-width: var(--container-xs);
  }

  .min-w-0 {
    min-width: 0;
  }

  .min-w-11 {
    min-width: calc(var(--spacing) * 11);
  }

  .min-w-80 {
    min-width: calc(var(--spacing) * 80);
  }

  .min-w-\[2px\] {
    min-width: 2px;
  }

  .min-w-\[8rem\] {
    min-width: 8rem;
  }

  .min-w-\[34rem\] {
    min-width: 34rem;
  }

  .min-w-\[38rem\] {
    min-width: 38rem;
  }

  .min-w-\[42rem\] {
    min-width: 42rem;
  }

  .min-w-\[44rem\] {
    min-width: 44rem;
  }

  .min-w-\[46rem\] {
    min-width: 46rem;
  }

  .min-w-\[64px\] {
    min-width: 64px;
  }

  .min-w-\[130px\] {
    min-width: 130px;
  }

  .min-w-\[140px\] {
    min-width: 140px;
  }

  .min-w-\[160px\] {
    min-width: 160px;
  }

  .min-w-\[170px\] {
    min-width: 170px;
  }

  .min-w-\[180px\] {
    min-width: 180px;
  }

  .min-w-\[220px\] {
    min-width: 220px;
  }

  .min-w-\[520px\] {
    min-width: 520px;
  }

  .min-w-\[Nrem\] {
    min-width: Nrem;
  }

  .flex-1 {
    flex: 1;
  }

  .flex-\[2\] {
    flex: 2;
  }

  .flex-auto {
    flex: auto;
  }

  .flex-none {
    flex: none;
  }

  .flex-shrink, .shrink {
    flex-shrink: 1;
  }

  .shrink-0 {
    flex-shrink: 0;
  }

  .grow {
    flex-grow: 1;
  }

  .basis-full {
    flex-basis: 100%;
  }

  .border-collapse {
    border-collapse: collapse;
  }

  .origin-bottom-left {
    transform-origin: 0 100%;
  }

  .origin-center {
    transform-origin: center;
  }

  .origin-top-left {
    transform-origin: 0 0;
  }

  .-translate-x-1 {
    --tw-translate-x: calc(var(--spacing) * -1);
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .-translate-y-1 {
    --tw-translate-y: calc(var(--spacing) * -1);
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .-translate-y-20 {
    --tw-translate-y: calc(var(--spacing) * -20);
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .translate-y-\[0\.15em\] {
    --tw-translate-y: .15em;
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .translate-y-\[2px\] {
    --tw-translate-y: 2px;
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .scale-95 {
    --tw-scale-x: 95%;
    --tw-scale-y: 95%;
    --tw-scale-z: 95%;
    scale: var(--tw-scale-x) var(--tw-scale-y);
  }

  .rotate-90 {
    rotate: 90deg;
  }

  .rotate-180 {
    rotate: 180deg;
  }

  .rotate-412 {
    rotate: 412deg;
  }

  .transform {
    transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );
  }

  .transform\! {
    transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, ) !important;
  }

  .animate-pulse {
    animation: var(--animate-pulse);
  }

  .cursor-\[var\(--cds-cursor-interactive\)\] {
    cursor: var(--cds-cursor-interactive);
  }

  .cursor-default {
    cursor: default;
  }

  .cursor-not-allowed {
    cursor: not-allowed;
  }

  .cursor-pointer {
    cursor: pointer;
  }

  .cursor-text {
    cursor: text;
  }

  .resize {
    resize: both;
  }

  .resize-none {
    resize: none;
  }

  .resize-y {
    resize: vertical;
  }

  .snap-x {
    scroll-snap-type: x var(--tw-scroll-snap-strictness);
  }

  .snap-start {
    scroll-snap-align: start;
  }

  .scroll-mt-4 {
    scroll-margin-top: calc(var(--spacing) * 4);
  }

  .scroll-mt-24 {
    scroll-margin-top: calc(var(--spacing) * 24);
  }

  .scroll-mt-28 {
    scroll-margin-top: calc(var(--spacing) * 28);
  }

  .list-disc {
    list-style-type: disc;
  }

  .list-none {
    list-style-type: none;
  }

  .grid-flow-col {
    grid-auto-flow: column;
  }

  .grid-cols-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .grid-cols-5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }

  .grid-cols-6 {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }

  .grid-cols-\[auto_1fr\] {
    grid-template-columns: auto 1fr;
  }

  .grid-cols-\[repeat\(auto-fill\,minmax\(88px\,1fr\)\)\] {
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  }

  .grid-rows-2 {
    grid-template-rows: repeat(2, minmax(0, 1fr));
  }

  .flex-col {
    flex-direction: column;
  }

  .flex-col-reverse {
    flex-direction: column-reverse;
  }

  .flex-row-reverse {
    flex-direction: row-reverse;
  }

  .flex-nowrap {
    flex-wrap: nowrap;
  }

  .flex-wrap {
    flex-wrap: wrap;
  }

  .place-items-center {
    place-items: center;
  }

  .content-start {
    align-content: flex-start;
  }

  .items-baseline {
    align-items: baseline;
  }

  .items-center {
    align-items: center;
  }

  .items-end {
    align-items: flex-end;
  }

  .items-start {
    align-items: flex-start;
  }

  .items-stretch {
    align-items: stretch;
  }

  .justify-between {
    justify-content: space-between;
  }

  .justify-center {
    justify-content: center;
  }

  .justify-end {
    justify-content: flex-end;
  }

  .justify-start {
    justify-content: flex-start;
  }

  .gap-0 {
    gap: 0;
  }

  .gap-0\.5 {
    gap: calc(var(--spacing) * .5);
  }

  .gap-1 {
    gap: var(--spacing);
  }

  .gap-1\.5 {
    gap: calc(var(--spacing) * 1.5);
  }

  .gap-2 {
    gap: calc(var(--spacing) * 2);
  }

  .gap-2\.5 {
    gap: calc(var(--spacing) * 2.5);
  }

  .gap-3 {
    gap: calc(var(--spacing) * 3);
  }

  .gap-3\.5 {
    gap: calc(var(--spacing) * 3.5);
  }

  .gap-4 {
    gap: calc(var(--spacing) * 4);
  }

  .gap-5 {
    gap: calc(var(--spacing) * 5);
  }

  .gap-6 {
    gap: calc(var(--spacing) * 6);
  }

  .gap-7 {
    gap: calc(var(--spacing) * 7);
  }

  .gap-8 {
    gap: calc(var(--spacing) * 8);
  }

  .gap-10 {
    gap: calc(var(--spacing) * 10);
  }

  .gap-12 {
    gap: calc(var(--spacing) * 12);
  }

  .gap-96 {
    gap: calc(var(--spacing) * 96);
  }

  .gap-\[2\.4cqw\] {
    gap: 2.4cqw;
  }

  .gap-\[2px\] {
    gap: 2px;
  }

  .gap-\[3px\] {
    gap: 3px;
  }

  .gap-\[4px\] {
    gap: 4px;
  }

  .gap-px {
    gap: 1px;
  }

  :where(.space-y-0\.5 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-1 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(var(--spacing) * var(--tw-space-y-reverse));
    margin-block-end: calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-1\.5 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-2 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-2\.5 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-3 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-4 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-5 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-6 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-7 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 7) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 7) * calc(1 - var(--tw-space-y-reverse)));
  }

  :where(.space-y-9 > :not(:last-child)) {
    --tw-space-y-reverse: 0;
    margin-block-start: calc(calc(var(--spacing) * 9) * var(--tw-space-y-reverse));
    margin-block-end: calc(calc(var(--spacing) * 9) * calc(1 - var(--tw-space-y-reverse)));
  }

  .gap-x-2 {
    column-gap: calc(var(--spacing) * 2);
  }

  .gap-x-2\.5 {
    column-gap: calc(var(--spacing) * 2.5);
  }

  .gap-x-3 {
    column-gap: calc(var(--spacing) * 3);
  }

  .gap-x-4 {
    column-gap: calc(var(--spacing) * 4);
  }

  .gap-x-5 {
    column-gap: calc(var(--spacing) * 5);
  }

  .gap-x-6 {
    column-gap: calc(var(--spacing) * 6);
  }

  .gap-x-7 {
    column-gap: calc(var(--spacing) * 7);
  }

  .gap-x-8 {
    column-gap: calc(var(--spacing) * 8);
  }

  .gap-x-10 {
    column-gap: calc(var(--spacing) * 10);
  }

  .gap-x-12 {
    column-gap: calc(var(--spacing) * 12);
  }

  .gap-x-48 {
    column-gap: calc(var(--spacing) * 48);
  }

  .gap-y-0\.5 {
    row-gap: calc(var(--spacing) * .5);
  }

  .gap-y-1 {
    row-gap: var(--spacing);
  }

  .gap-y-1\.5 {
    row-gap: calc(var(--spacing) * 1.5);
  }

  .gap-y-2 {
    row-gap: calc(var(--spacing) * 2);
  }

  .gap-y-2\.5 {
    row-gap: calc(var(--spacing) * 2.5);
  }

  .gap-y-3 {
    row-gap: calc(var(--spacing) * 3);
  }

  .gap-y-4 {
    row-gap: calc(var(--spacing) * 4);
  }

  .gap-y-5 {
    row-gap: calc(var(--spacing) * 5);
  }

  .gap-y-8 {
    row-gap: calc(var(--spacing) * 8);
  }

  .gap-y-10 {
    row-gap: calc(var(--spacing) * 10);
  }

  .gap-y-32 {
    row-gap: calc(var(--spacing) * 32);
  }

  :where(.divide-y > :not(:last-child)) {
    --tw-divide-y-reverse: 0;
    border-bottom-style: var(--tw-border-style);
    border-top-style: var(--tw-border-style);
    border-top-width: calc(1px * var(--tw-divide-y-reverse));
    border-bottom-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  }

  :where(.divide-ink-200 > :not(:last-child)) {
    border-color: var(--color-ink-200);
  }

  .self-center {
    align-self: center;
  }

  .self-end {
    align-self: flex-end;
  }

  .self-start {
    align-self: flex-start;
  }

  .self-stretch {
    align-self: stretch;
  }

  .justify-self-stretch {
    justify-self: stretch;
  }

  .truncate {
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
  }

  .overflow-auto {
    overflow: auto;
  }

  .overflow-hidden {
    overflow: hidden;
  }

  .overflow-visible {
    overflow: visible;
  }

  .overflow-x-auto {
    overflow-x: auto;
  }

  .overflow-x-hidden {
    overflow-x: hidden;
  }

  .overflow-y-auto {
    overflow-y: auto;
  }

  .rounded {
    border-radius: .25rem;
  }

  .rounded-2xl {
    border-radius: var(--radius-2xl);
  }

  .rounded-\[1\.1rem\] {
    border-radius: 1.1rem;
  }

  .rounded-\[1\.6rem\] {
    border-radius: 1.6rem;
  }

  .rounded-\[1px\] {
    border-radius: 1px;
  }

  .rounded-\[2px\] {
    border-radius: 2px;
  }

  .rounded-\[3px\] {
    border-radius: 3px;
  }

  .rounded-\[4px\] {
    border-radius: 4px;
  }

  .rounded-\[6px\] {
    border-radius: 6px;
  }

  .rounded-\[10px\] {
    border-radius: 10px;
  }

  .rounded-\[34px\] {
    border-radius: 34px;
  }

  .rounded-\[inherit\] {
    border-radius: inherit;
  }

  .rounded-full {
    border-radius: 3.40282e38px;
  }

  .rounded-lg {
    border-radius: var(--radius-lg);
  }

  .rounded-md {
    border-radius: var(--radius-md);
  }

  .rounded-none {
    border-radius: 0;
  }

  .rounded-panel {
    border-radius: var(--radius-panel);
  }

  .rounded-sm {
    border-radius: var(--radius-sm);
  }

  .rounded-xl {
    border-radius: var(--radius-xl);
  }

  .rounded-l-none {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }

  .rounded-tl-none {
    border-top-left-radius: 0;
  }

  .rounded-tl-sm {
    border-top-left-radius: var(--radius-sm);
  }

  .rounded-r-none {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  .rounded-br-sm {
    border-bottom-right-radius: var(--radius-sm);
  }

  .rounded-bl-none {
    border-bottom-left-radius: 0;
  }

  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }

  .border-0 {
    border-style: var(--tw-border-style);
    border-width: 0;
  }

  .border-2 {
    border-style: var(--tw-border-style);
    border-width: 2px;
  }

  .border-\[3px\] {
    border-style: var(--tw-border-style);
    border-width: 3px;
  }

  .border-y {
    border-block-style: var(--tw-border-style);
    border-block-width: 1px;
  }

  .border-t {
    border-top-style: var(--tw-border-style);
    border-top-width: 1px;
  }

  .border-b {
    border-bottom-style: var(--tw-border-style);
    border-bottom-width: 1px;
  }

  .border-l {
    border-left-style: var(--tw-border-style);
    border-left-width: 1px;
  }

  .border-l-2 {
    border-left-style: var(--tw-border-style);
    border-left-width: 2px;
  }

  .border-l-\[3px\] {
    border-left-style: var(--tw-border-style);
    border-left-width: 3px;
  }

  .border-dashed {
    --tw-border-style: dashed;
    border-style: dashed;
  }

  .border-dotted {
    --tw-border-style: dotted;
    border-style: dotted;
  }

  .border-\[color\:var\(--frame-line\)\] {
    border-color: var(--frame-line);
  }

  .border-\[var\(--stu-line\)\] {
    border-color: var(--stu-line);
  }

  .border-beam {
    border-color: var(--color-beam);
  }

  .border-beam\/35 {
    border-color: #22e0d559;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-beam\/35 {
      border-color: color-mix(in oklab, var(--color-beam) 35%, transparent);
    }
  }

  .border-beam\/40 {
    border-color: #22e0d566;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-beam\/40 {
      border-color: color-mix(in oklab, var(--color-beam) 40%, transparent);
    }
  }

  .border-beam\/50 {
    border-color: #22e0d580;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-beam\/50 {
      border-color: color-mix(in oklab, var(--color-beam) 50%, transparent);
    }
  }

  .border-beam\/60 {
    border-color: #22e0d599;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-beam\/60 {
      border-color: color-mix(in oklab, var(--color-beam) 60%, transparent);
    }
  }

  .border-cleared {
    border-color: var(--color-cleared);
  }

  .border-cleared\/40 {
    border-color: #b8f04a66;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-cleared\/40 {
      border-color: color-mix(in oklab, var(--color-cleared) 40%, transparent);
    }
  }

  .border-flag {
    border-color: var(--color-flag);
  }

  .border-flag\/40 {
    border-color: #ff2e8e66;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-flag\/40 {
      border-color: color-mix(in oklab, var(--color-flag) 40%, transparent);
    }
  }

  .border-flag\/50 {
    border-color: #ff2e8e80;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-flag\/50 {
      border-color: color-mix(in oklab, var(--color-flag) 50%, transparent);
    }
  }

  .border-flag\/60 {
    border-color: #ff2e8e99;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-flag\/60 {
      border-color: color-mix(in oklab, var(--color-flag) 60%, transparent);
    }
  }

  .border-ink-000 {
    border-color: var(--color-ink-000);
  }

  .border-ink-200 {
    border-color: var(--color-ink-200);
  }

  .border-ink-200\/60 {
    border-color: #2a283399;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-ink-200\/60 {
      border-color: color-mix(in oklab, var(--color-ink-200) 60%, transparent);
    }
  }

  .border-ink-300 {
    border-color: var(--color-ink-300);
  }

  .border-ink-400 {
    border-color: var(--color-ink-400);
  }

  .border-ink-400\/50 {
    border-color: #8b859980;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-ink-400\/50 {
      border-color: color-mix(in oklab, var(--color-ink-400) 50%, transparent);
    }
  }

  .border-ink-400\/60 {
    border-color: #8b859999;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-ink-400\/60 {
      border-color: color-mix(in oklab, var(--color-ink-400) 60%, transparent);
    }
  }

  .border-ink-400\/70 {
    border-color: #8b8599b3;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-ink-400\/70 {
      border-color: color-mix(in oklab, var(--color-ink-400) 70%, transparent);
    }
  }

  .border-ink-900 {
    border-color: var(--color-ink-900);
  }

  .border-judge {
    border-color: var(--color-judge);
  }

  .border-judge\/40 {
    border-color: #b49be866;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .border-judge\/40 {
      border-color: color-mix(in oklab, var(--color-judge) 40%, transparent);
    }
  }

  .border-transparent {
    border-color: #0000;
  }

  .border-l-cleared {
    border-left-color: var(--color-cleared);
  }

  .border-l-ink-200 {
    border-left-color: var(--color-ink-200);
  }

  .border-l-judge {
    border-left-color: var(--color-judge);
  }

  .bg-\[color\:var\(--readout\)\] {
    background-color: var(--readout);
  }

  .bg-\[var\(--cds-page-bg\)\] {
    background-color: var(--cds-page-bg);
  }

  .bg-\[var\(--fill-cleared\)\] {
    background-color: var(--fill-cleared);
  }

  .bg-\[var\(--fill-judge\)\] {
    background-color: var(--fill-judge);
  }

  .bg-beam {
    background-color: var(--color-beam);
  }

  .bg-beam-dim {
    background-color: var(--color-beam-dim);
  }

  .bg-beam\/5 {
    background-color: #22e0d50d;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-beam\/5 {
      background-color: color-mix(in oklab, var(--color-beam) 5%, transparent);
    }
  }

  .bg-beam\/10 {
    background-color: #22e0d51a;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-beam\/10 {
      background-color: color-mix(in oklab, var(--color-beam) 10%, transparent);
    }
  }

  .bg-black\/40 {
    background-color: #0006;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-black\/40 {
      background-color: color-mix(in oklab, var(--color-black) 40%, transparent);
    }
  }

  .bg-blue-100 {
    background-color: var(--color-blue-100);
  }

  .bg-blue-500 {
    background-color: var(--color-blue-500);
  }

  .bg-cleared {
    background-color: var(--color-cleared);
  }

  .bg-flag {
    background-color: var(--color-flag);
  }

  .bg-flag-dim {
    background-color: var(--color-flag-dim);
  }

  .bg-flag\/5 {
    background-color: #ff2e8e0d;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-flag\/5 {
      background-color: color-mix(in oklab, var(--color-flag) 5%, transparent);
    }
  }

  .bg-flag\/10 {
    background-color: #ff2e8e1a;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-flag\/10 {
      background-color: color-mix(in oklab, var(--color-flag) 10%, transparent);
    }
  }

  .bg-gray-700 {
    background-color: var(--color-gray-700);
  }

  .bg-green-100 {
    background-color: var(--color-green-100);
  }

  .bg-green-500 {
    background-color: var(--color-green-500);
  }

  .bg-ink-000 {
    background-color: var(--color-ink-000);
  }

  .bg-ink-000\/70 {
    background-color: #0e0d12b3;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-ink-000\/70 {
      background-color: color-mix(in oklab, var(--color-ink-000) 70%, transparent);
    }
  }

  .bg-ink-000\/90 {
    background-color: #0e0d12e6;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-ink-000\/90 {
      background-color: color-mix(in oklab, var(--color-ink-000) 90%, transparent);
    }
  }

  .bg-ink-050 {
    background-color: var(--color-ink-050);
  }

  .bg-ink-100 {
    background-color: var(--color-ink-100);
  }

  .bg-ink-150 {
    background-color: var(--color-ink-150);
  }

  .bg-ink-200 {
    background-color: var(--color-ink-200);
  }

  .bg-ink-300 {
    background-color: var(--color-ink-300);
  }

  .bg-ink-400 {
    background-color: var(--color-ink-400);
  }

  .bg-ink-600 {
    background-color: var(--color-ink-600);
  }

  .bg-ink-600\/50 {
    background-color: #bdb8c880;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-ink-600\/50 {
      background-color: color-mix(in oklab, var(--color-ink-600) 50%, transparent);
    }
  }

  .bg-ink-900 {
    background-color: var(--color-ink-900);
  }

  .bg-ink-900\/40 {
    background-color: #f0eef466;
  }

  @supports (color: color-mix(in lab, red, red)) {
    .bg-ink-900\/40 {
      background-color: color-mix(in oklab, var(--color-ink-900) 40%, transparent);
    }
  }

  .bg-judge {
    background-color: var(--color-judge);
  }

  .bg-neutral-200 {
    background-color: var(--color-neutral-200);
  }

  .bg-neutral-300 {
    background-color: var(--color-neutral-300);
  }

  .bg-neutral-800 {
    background-color: var(--color-neutral-800);
  }

  .bg-orange-100 {
    background-color: var(--color-orange-100);
  }

  .bg-red-100 {
    background-color: var(--color-red-100);
  }

  .bg-transparent {
    background-color: #0000;
  }

  .bg-violet-100 {
    background-color: var(--color-violet-100);
  }

  .bg-white {
    background-color: var(--color-white);
  }

  .bg-yellow-100 {
    background-color: var(--color-yellow-100);
  }

  .bg-yellow-500 {
    background-color: var(--color-yellow-500);
  }

  .bg-\[linear-gradient\(150deg\,var\(--color-ink-300\)\,var\(--color-ink-200\)\)\] {
    background-image: linear-gradient(150deg,var(--color-ink-300),var(--color-ink-200));
  }

  .fill-current {
    fill: currentColor;
  }

  .object-contain {
    object-fit: contain;
  }

  .object-cover {
    object-fit: cover;
  }

  .p-0 {
    padding: 0;
  }

  .p-0\.5 {
    padding: calc(var(--spacing) * .5);
  }

  .p-1 {
    padding: var(--spacing);
  }

  .p-1\.5 {
    padding: calc(var(--spacing) * 1.5);
  }

  .p-2 {
    padding: calc(var(--spacing) * 2);
  }

  .p-2\.5 {
    padding: calc(var(--spacing) * 2.5);
  }

  .p-3 {
    padding: calc(var(--spacing) * 3);
  }

  .p-3\.5 {
    padding: calc(var(--spacing) * 3.5);
  }

  .p-4 {
    padding: calc(var(--spacing) * 4);
  }

  .p-5 {
    padding: calc(var(--spacing) * 5);
  }

  .p-6 {
    padding: calc(var(--spacing) * 6);
  }

  .p-7 {
    padding: calc(var(--spacing) * 7);
  }

  .p-9 {
    padding: calc(var(--spacing) * 9);
  }

  .p-\[7cqw\] {
    padding: 7cqw;
  }

  .px-0 {
    padding-inline: 0;
  }

  .px-0\.5 {
    padding-inline: calc(var(--spacing) * .5);
  }

  .px-1 {
    padding-inline: var(--spacing);
  }

  .px-1\.5 {
    padding-inline: calc(var(--spacing) * 1.5);
  }

  .px-2 {
    padding-inline: calc(var(--spacing) * 2);
  }

  .px-2\.5 {
    padding-inline: calc(var(--spacing) * 2.5);
  }

  .px-3 {
    padding-inline: calc(var(--spacing) * 3);
  }

  .px-3\.5 {
    padding-inline: calc(var(--spacing) * 3.5);
  }

  .px-4 {
    padding-inline: calc(var(--spacing) * 4);
  }

  .px-5 {
    padding-inline: calc(var(--spacing) * 5);
  }

  .px-6 {
    padding-inline: calc(var(--spacing) * 6);
  }

  .px-8 {
    padding-inline: calc(var(--spacing) * 8);
  }

  .px-40 {
    padding-inline: calc(var(--spacing) * 40);
  }

  .py-0\.5 {
    padding-block: calc(var(--spacing) * .5);
  }

  .py-1 {
    padding-block: var(--spacing);
  }

  .py-1\.5 {
    padding-block: calc(var(--spacing) * 1.5);
  }

  .py-2 {
    padding-block: calc(var(--spacing) * 2);
  }

  .py-2\.5 {
    padding-block: calc(var(--spacing) * 2.5);
  }

  .py-3 {
    padding-block: calc(var(--spacing) * 3);
  }

  .py-3\.5 {
    padding-block: calc(var(--spacing) * 3.5);
  }

  .py-4 {
    padding-block: calc(var(--spacing) * 4);
  }

  .py-5 {
    padding-block: calc(var(--spacing) * 5);
  }

  .py-6 {
    padding-block: calc(var(--spacing) * 6);
  }

  .py-7 {
    padding-block: calc(var(--spacing) * 7);
  }

  .py-8 {
    padding-block: calc(var(--spacing) * 8);
  }

  .py-9 {
    padding-block: calc(var(--spacing) * 9);
  }

  .py-10 {
    padding-block: calc(var(--spacing) * 10);
  }

  .py-12 {
    padding-block: calc(var(--spacing) * 12);
  }

  .py-14 {
    padding-block: calc(var(--spacing) * 14);
  }

  .py-16 {
    padding-block: calc(var(--spacing) * 16);
  }

  .py-24 {
    padding-block: calc(var(--spacing) * 24);
  }

  .pt-0 {
    padding-top: 0;
  }

  .pt-1 {
    padding-top: var(--spacing);
  }

  .pt-1\.5 {
    padding-top: calc(var(--spacing) * 1.5);
  }

  .pt-2 {
    padding-top: calc(var(--spacing) * 2);
  }

  .pt-2\.5 {
    padding-top: calc(var(--spacing) * 2.5);
  }

  .pt-3 {
    padding-top: calc(var(--spacing) * 3);
  }

  .pt-4 {
    padding-top: calc(var(--spacing) * 4);
  }

  .pt-5 {
    padding-top: calc(var(--spacing) * 5);
  }

  .pt-6 {
    padding-top: calc(var(--spacing) * 6);
  }

  .pt-8 {
    padding-top: calc(var(--spacing) * 8);
  }

  .pt-10 {
    padding-top: calc(var(--spacing) * 10);
  }

  .pt-16 {
    padding-top: calc(var(--spacing) * 16);
  }

  .pt-20 {
    padding-top: calc(var(--spacing) * 20);
  }

  .pr-0 {
    padding-right: 0;
  }

  .pr-1 {
    padding-right: var(--spacing);
  }

  .pr-2 {
    padding-right: calc(var(--spacing) * 2);
  }

  .pr-3 {
    padding-right: calc(var(--spacing) * 3);
  }

  .pr-4 {
    padding-right: calc(var(--spacing) * 4);
  }

  .pr-5 {
    padding-right: calc(var(--spacing) * 5);
  }

  .pr-6 {
    padding-right: calc(var(--spacing) * 6);
  }

  .pb-0\.5 {
    padding-bottom: calc(var(--spacing) * .5);
  }

  .pb-1 {
    padding-bottom: var(--spacing);
  }

  .pb-1\.5 {
    padding-bottom: calc(var(--spacing) * 1.5);
  }

  .pb-2 {
    padding-bottom: calc(var(--spacing) * 2);
  }

  .pb-2\.5 {
    padding-bottom: calc(var(--spacing) * 2.5);
  }

  .pb-3 {
    padding-bottom: calc(var(--spacing) * 3);
  }

  .pb-4 {
    padding-bottom: calc(var(--spacing) * 4);
  }

  .pb-5 {
    padding-bottom: calc(var(--spacing) * 5);
  }

  .pb-7 {
    padding-bottom: calc(var(--spacing) * 7);
  }

  .pb-8 {
    padding-bottom: calc(var(--spacing) * 8);
  }

  .pb-10 {
    padding-bottom: calc(var(--spacing) * 10);
  }

  .pb-16 {
    padding-bottom: calc(var(--spacing) * 16);
  }

  .pb-24 {
    padding-bottom: calc(var(--spacing) * 24);
  }

  .pb-\[calc\(env\(safe-area-inset-bottom\)\+0\.5rem\)\] {
    padding-bottom: calc(env(safe-area-inset-bottom) + .5rem);
  }

  .\!pl-\[6px\] {
    padding-left: 6px !important;
  }

  .pl-0 {
    padding-left: 0;
  }

  .pl-1 {
    padding-left: var(--spacing);
  }

  .pl-1\.5 {
    padding-left: calc(var(--spacing) * 1.5);
  }

  .pl-2 {
    padding-left: calc(var(--spacing) * 2);
  }

  .pl-2\.5 {
    padding-left: calc(var(--spacing) * 2.5);
  }

  .pl-3 {
    padding-left: calc(var(--spacing) * 3);
  }

  .pl-4 {
    padding-left: calc(var(--spacing) * 4);
  }

  .pl-5 {
    padding-left: calc(var(--spacing) * 5);
  }

  .pl-6 {
    padding-left: calc(var(--spacing) * 6);
  }

  .text-center {
    text-align: center;
  }

  .text-end {
    text-align: end;
  }

  .text-left {
    text-align: left;
  }

  .text-right {
    text-align: right;
  }

  .align-baseline {
    vertical-align: baseline;
  }

  .align-bottom {
    vertical-align: bottom;
  }

  .align-middle {
    vertical-align: middle;
  }

  .align-top {
    vertical-align: top;
  }

  .font-display {
    font-family: var(--font-display);
  }

  .font-mono {
    font-family: var(--font-mono);
  }

  .font-sans {
    font-family: var(--font-sans);
  }

  .font-serif {
    font-family: var(--font-serif);
  }

  .text-\[1\.4rem\] {
    font-size: 1.4rem;
  }

  .text-\[1\.25rem\] {
    font-size: 1.25rem;
  }

  .text-\[9px\] {
    font-size: 9px;
  }

  .text-\[11px\] {
    font-size: 11px;
  }

  .text-\[12\.5px\] {
    font-size: 12.5px;
  }

  .text-\[12px\] {
    font-size: 12px;
  }

  .text-\[13\.5px\] {
    font-size: 13.5px;
  }

  .text-\[14px\] {
    font-size: 14px;
  }

  .text-\[15px\] {
    font-size: 15px;
  }

  .text-\[16px\] {
    font-size: 16px;
  }

  .text-\[17px\] {
    font-size: 17px;
  }

  .text-\[20px\] {
    font-size: 20px;
  }

  .text-\[24px\] {
    font-size: 24px;
  }

  .text-\[26px\] {
    font-size: 26px;
  }

  .text-\[34px\] {
    font-size: 34px;
  }

  .text-\[clamp\(0\.9rem\,2\.6vw\,1\.15rem\)\] {
    font-size: clamp(.9rem, 2.6vw, 1.15rem);
  }

  .text-\[clamp\(0\.85rem\,2\.4vw\,1\.05rem\)\] {
    font-size: clamp(.85rem, 2.4vw, 1.05rem);
  }

  .text-\[clamp\(0\.95rem\,2\.8vw\,1\.2rem\)\] {
    font-size: clamp(.95rem, 2.8vw, 1.2rem);
  }

  .text-\[clamp\(1\.1rem\,2\.6vw\,1\.55rem\)\] {
    font-size: clamp(1.1rem, 2.6vw, 1.55rem);
  }

  .text-\[clamp\(1\.1rem\,3\.4vw\,1\.6rem\)\] {
    font-size: clamp(1.1rem, 3.4vw, 1.6rem);
  }

  .text-\[clamp\(1\.4rem\,5vw\,2\.4rem\)\] {
    font-size: clamp(1.4rem, 5vw, 2.4rem);
  }

  .text-\[clamp\(1rem\,3vw\,1\.35rem\)\] {
    font-size: clamp(1rem, 3vw, 1.35rem);
  }

  .text-\[clamp\(2\.4rem\,6vw\,3\.4rem\)\] {
    font-size: clamp(2.4rem, 6vw, 3.4rem);
  }

  .text-\[clamp\(2\.6rem\,6vw\,4rem\)\] {
    font-size: clamp(2.6rem, 6vw, 4rem);
  }

  .text-\[clamp\(3rem\,13vw\,5\.5rem\)\] {
    font-size: clamp(3rem, 13vw, 5.5rem);
  }

  .leading-4 {
    --tw-leading: calc(var(--spacing) * 4);
    line-height: calc(var(--spacing) * 4);
  }

  .leading-5 {
    --tw-leading: calc(var(--spacing) * 5);
    line-height: calc(var(--spacing) * 5);
  }

  .leading-\[0\.8\] {
    --tw-leading: .8;
    line-height: .8;
  }

  .leading-\[0\.9\] {
    --tw-leading: .9;
    line-height: .9;
  }

  .leading-\[0\.98\] {
    --tw-leading: .98;
    line-height: .98;
  }

  .leading-\[1\.05\] {
    --tw-leading: 1.05;
    line-height: 1.05;
  }

  .leading-\[1\.55\] {
    --tw-leading: 1.55;
    line-height: 1.55;
  }

  .leading-\[16px\] {
    --tw-leading: 16px;
    line-height: 16px;
  }

  .leading-\[18px\] {
    --tw-leading: 18px;
    line-height: 18px;
  }

  .leading-\[20px\] {
    --tw-leading: 20px;
    line-height: 20px;
  }

  .leading-\[21px\] {
    --tw-leading: 21px;
    line-height: 21px;
  }

  .leading-\[22px\] {
    --tw-leading: 22px;
    line-height: 22px;
  }

  .leading-\[23px\] {
    --tw-leading: 23px;
    line-height: 23px;
  }

  .leading-\[24px\] {
    --tw-leading: 24px;
    line-height: 24px;
  }

  .leading-\[25px\] {
    --tw-leading: 25px;
    line-height: 25px;
  }

  .leading-\[26px\] {
    --tw-leading: 26px;
    line-height: 26px;
  }

  .leading-\[27px\] {
    --tw-leading: 27px;
    line-height: 27px;
  }

  .leading-\[28px\] {
    --tw-leading: 28px;
    line-height: 28px;
  }

  .leading-\[30px\] {
    --tw-leading: 30px;
    line-height: 30px;
  }

  .leading-none {
    --tw-leading: 1;
    line-height: 1;
  }

  .leading-relaxed {
    --tw-leading: var(--leading-relaxed);
    line-height: var(--leading-relaxed);
  }

  .leading-snug {
    --tw-leading: var(--leading-snug);
    line-height: var(--leading-snug);
  }

  .leading-tight {
    --tw-leading: var(--leading-tight);
    line-height: var(--leading-tight);
  }

  .font-bold {
    --tw-font-weight: var(--font-weight-bold);
    font-weight: var(--font-weight-bold);
  }

  .font-extrabold {
    --tw-font-weight: var(--font-weight-extrabold);
    font-weight: var(--font-weight-extrabold);
  }

  .font-medium {
    --tw-font-weight: var(--font-weight-medium);
    font-weight: var(--font-weight-medium);
  }

  .font-normal {
    --tw-font-weight: var(--font-weight-normal);
    font-weight: var(--font-weight-normal);
  }

  .font-semibold {
    --tw-font-weight: var(--font-weight-semibold);
    font-weight: var(--font-weight-semibold);
  }

  .tracking-\[-0\.01em\] {
    --tw-tracking: -.01em;
    letter-spacing: -.01em;
  }

  .tracking-\[-0\.02em\] {
    --tw-tracking: -.02em;
    letter-spacing: -.02em;
  }

  .tracking-\[-0\.03em\] {
    --tw-tracking: -.03em;
    letter-spacing: -.03em;
  }

  .tracking-\[-0\.005em\] {
    --tw-tracking: -.005em;
    letter-spacing: -.005em;
  }

  .tracking-\[-0\.05em\] {
    --tw-tracking: -.05em;
    letter-spacing: -.05em;
  }

  .tracking-\[0\.1em\] {
    --tw-tracking: .1em;
    letter-spacing: .1em;
  }

  .tracking-\[0\.04em\] {
    --tw-tracking: .04em;
    letter-spacing: .04em;
  }

  .tracking-\[0\.06em\] {
    --tw-tracking: .06em;
    letter-spacing: .06em;
  }

  .tracking-\[0\.08em\] {
    --tw-tracking: .08em;
    letter-spacing: .08em;
  }

  .tracking-\[0\.09em\] {
    --tw-tracking: .09em;
    letter-spacing: .09em;
  }

  .tracking-\[0\.14em\] {
    --tw-tracking: .14em;
    letter-spacing: .14em;
  }

  .tracking-\[0\.16em\] {
    --tw-tracking: .16em;
    letter-spacing: .16em;
  }

  .tracking-normal {
    --tw-tracking: var(--tracking-normal);
    letter-spacing: var(--tracking-normal);
  }

  .tracking-tight {
    --tw-tracking: var(--tracking-tight);
    letter-spacing: var(--tracking-tight);
  }

  .text-balance {
    text-wrap: balance;
  }

  .text-wrap {
    text-wrap: wrap;
  }

  .break-words {
    overflow-wrap: break-word;
  }

  .break-all {
    word-break: break-all;
  }

  .text-ellipsis {
    text-overflow: ellipsis;
  }

  .whitespace-normal {
    white-space: normal;
  }

  .whitespace-nowrap {
    white-space: nowrap;
  }

  .whitespace-pre {
    white-space: pre;
  }

  .whitespace-pre-wrap {
    white-space: pre-wrap;
  }

  .text-\[Npx\] {
    color: Npx;
  }

  .text-\[color\:var\(--readout\)\] {
    color: var(--readout);
  }

  .text-\[color\:var\(--readout-hi\)\] {
    color: var(--readout-hi);
  }

  .text-\[color\:var\(--stu-ink-2\)\] {
    color: var(--stu-ink-2);
  }

  .text-\[var\(--on-judge-wash\)\] {
    color: var(--on-judge-wash);
  }

  .text-beam {
    color: var(--color-beam);
  }

  .text-blue-600 {
    color: var(--color-blue-600);
  }

  .text-cleared {
    color: var(--color-cleared);
  }

  .text-current {
    color: currentColor;
  }

  .text-flag {
    color: var(--color-flag);
  }

  .text-green-600 {
    color: var(--color-green-600);
  }

  .text-ink-000 {
    color: var(--color-ink-000);
  }

  .text-ink-050 {
    color: var(--color-ink-050);
  }

  .text-ink-200 {
    color: var(--color-ink-200);
  }

  .text-ink-300 {
    color: var(--color-ink-300);
  }

  .text-ink-400 {
    color: var(--color-ink-400);
  }

  .text-ink-500 {
    color: var(--color-ink-500);
  }

  .text-ink-600 {
    color: var(--color-ink-600);
  }

  .text-ink-900 {
    color: var(--color-ink-900);
  }

  .text-judge {
    color: var(--color-judge);
  }

  .text-neutral-400 {
    color: var(--color-neutral-400);
  }

  .text-neutral-500 {
    color: var(--color-neutral-500);
  }

  .text-neutral-800 {
    color: var(--color-neutral-800);
  }

  .text-orange-600 {
    color: var(--color-orange-600);
  }

  .text-red-600 {
    color: var(--color-red-600);
  }

  .text-violet-600 {
    color: var(--color-violet-600);
  }

  .text-white {
    color: var(--color-white);
  }

  .text-yellow-600 {
    color: var(--color-yellow-600);
  }

  .capitalize {
    text-transform: capitalize;
  }

  .lowercase {
    text-transform: lowercase;
  }

  .uppercase {
    text-transform: uppercase;
  }

  .italic {
    font-style: italic;
  }

  .not-italic {
    font-style: normal;
  }

  .ordinal {
    --tw-ordinal: ordinal;
    font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, );
  }

  .tabular-nums {
    --tw-numeric-spacing: tabular-nums;
    font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, );
  }

  .line-through {
    text-decoration-line: line-through;
  }

  .overline {
    text-decoration-line: overline;
  }

  .underline {
    text-decoration-line: underline;
  }

  .decoration-flag {
    -webkit-text-decoration-color: var(--color-flag);
    -webkit-text-decoration-color: var(--color-flag);
    text-decoration-color: var(--color-flag);
  }

  .decoration-ink-400 {
    -webkit-text-decoration-color: var(--color-ink-400);
    -webkit-text-decoration-color: var(--color-ink-400);
    text-decoration-color: var(--color-ink-400);
  }

  .decoration-2 {
    text-decoration-thickness: 2px;
  }

  .underline-offset-2 {
    text-underline-offset: 2px;
  }

  .underline-offset-4 {
    text-underline-offset: 4px;
  }

  .antialiased {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  .accent-\[var\(--color-beam\)\], .accent-beam {
    accent-color: var(--color-beam);
  }

  .opacity-0 {
    opacity: 0;
  }

  .opacity-30 {
    opacity: .3;
  }

  .opacity-40 {
    opacity: .4;
  }

  .opacity-50 {
    opacity: .5;
  }

  .opacity-60 {
    opacity: .6;
  }

  .opacity-70 {
    opacity: .7;
  }

  .shadow {
    --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-2xl {
    --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, #00000040);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[0_18px_44px_rgba\(0\,0\,0\,\.55\)\] {
    --tw-shadow: 0 18px 44px var(--tw-shadow-color, #0000008c);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[0_20px_50px_rgba\(0\,0\,0\,\.55\)\] {
    --tw-shadow: 0 20px 50px var(--tw-shadow-color, #0000008c);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[0_24px_60px_-30px_rgba\(0\,0\,0\,0\.55\)\] {
    --tw-shadow: 0 24px 60px -30px var(--tw-shadow-color, #0000008c);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[0_30px_80px_rgba\(0\,0\,0\,\.5\)\] {
    --tw-shadow: 0 30px 80px var(--tw-shadow-color, #00000080);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[0_30px_80px_rgba\(0\,0\,0\,\.6\)\] {
    --tw-shadow: 0 30px 80px var(--tw-shadow-color, #0009);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[inset_0_1px_0_0_var\(--color-ink-300\)\] {
    --tw-shadow: inset 0 1px 0 0 var(--tw-shadow-color, var(--color-ink-300));
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-\[inset_0_1px_0_0_var\(--color-ink-400\)\] {
    --tw-shadow: inset 0 1px 0 0 var(--tw-shadow-color, var(--color-ink-400));
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-lg {
    --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-md {
    --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, #0000001a), 0 2px 4px -2px var(--tw-shadow-color, #0000001a);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-none {
    --tw-shadow: 0 0 #0000;
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-sm {
    --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .shadow-xl {
    --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, #0000001a), 0 8px 10px -6px var(--tw-shadow-color, #0000001a);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .ring, .ring-1 {
    --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .ring-2 {
    --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .\[box-shadow\:0_0_0_2px_var\(--cds-page-bg\)\] {
    box-shadow: 0 0 0 2px var(--cds-page-bg);
  }

  .ring-beam {
    --tw-ring-color: var(--color-beam);
  }

  .ring-flag {
    --tw-ring-color: var(--color-flag);
  }

  .ring-ink-400 {
    --tw-ring-color: var(--color-ink-400);
  }

  .ring-offset-2 {
    --tw-ring-offset-width: 2px;
    --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  }

  .ring-offset-ink-050 {
    --tw-ring-offset-color: var(--color-ink-050);
  }

  .outline {
    outline-style: var(--tw-outline-style);
    outline-width: 1px;
  }

  .blur {
    --tw-blur: blur(8px);
    filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
  }

  .drop-shadow {
    --tw-drop-shadow-size: drop-shadow(0 1px 2px var(--tw-drop-shadow-color, #0000001a)) drop-shadow(0 1px 1px var(--tw-drop-shadow-color, #0000000f));
    --tw-drop-shadow: drop-shadow(0 1px 2px #0000001a) drop-shadow(0 1px 1px #0000000f);
    filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
  }

  .invert {
    --tw-invert: invert(100%);
    filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
  }

  .filter {
    filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );
  }

  .backdrop-blur-md {
    --tw-backdrop-blur: blur(var(--blur-md));
    -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
    backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
  }

  .backdrop-blur-sm {
    --tw-backdrop-blur: blur(var(--blur-sm));
    -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
    backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
  }

  .backdrop-filter {
    -webkit-backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
    backdrop-filter: var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );
  }

  .transition {
    transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-\[background-color\,box-shadow\,color\] {
    transition-property: background-color, box-shadow, color;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-\[opacity\,transform\] {
    transition-property: opacity, transform;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-all {
    transition-property: all;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-colors {
    transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-opacity {
    transition-property: opacity;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-shadow {
    transition-property: box-shadow;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .transition-transform {
    transition-property: transform, translate, scale, rotate;
    transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
    transition-duration: var(--tw-duration, var(--default-transition-duration));
  }

  .delay-0 {
    transition-delay: 0s;
  }

  .duration-150 {
    --tw-duration: .15s;
    transition-duration: .15s;
  }

  .duration-200 {
    --tw-duration: .2s;
    transition-duration: .2s;
  }

  .duration-300 {
    --tw-duration: .3s;
    transition-duration: .3s;
  }

  .duration-500 {
    --tw-duration: .5s;
    transition-duration: .5s;
  }

  .ease-in-out {
    --tw-ease: var(--ease-in-out);
    transition-timing-function: var(--ease-in-out);
  }

  .ease-out {
    --tw-ease: var(--ease-out);
    transition-timing-function: var(--ease-out);
  }

  .outline-none {
    --tw-outline-style: none;
    outline-style: none;
  }

  .select-all {
    -webkit-user-select: all;
    user-select: all;
  }

  .select-none {
    -webkit-user-select: none;
    user-select: none;
  }

  .\[--cds-stack-overlap\:calc\(var\(--cds-avatar-sm\)\*0\.25\)\] {
    --cds-stack-overlap: calc(var(--cds-avatar-sm) * .25);
  }

  .block-1 {
    block-size: var(--spacing);
  }

  .block-2 {
    block-size: calc(var(--spacing) * 2);
  }

  .group-open\:rotate-90:is(:where(.group):is([open], :popover-open, :open) *) {
    rotate: 90deg;
  }

  .group-open\:rotate-180:is(:where(.group):is([open], :popover-open, :open) *) {
    rotate: 180deg;
  }

  @media (hover: hover) {
    .group-hover\:border-ink-400:is(:where(.group):hover *) {
      border-color: var(--color-ink-400);
    }

    .group-hover\:bg-ink-900:is(:where(.group):hover *) {
      background-color: var(--color-ink-900);
    }

    .group-hover\:text-ink-600:is(:where(.group):hover *) {
      color: var(--color-ink-600);
    }

    .group-hover\:underline:is(:where(.group):hover *) {
      text-decoration-line: underline;
    }

    .group-hover\:opacity-100:is(:where(.group):hover *) {
      opacity: 1;
    }
  }

  .group-focus-visible\/btn\:shadow-\[inset_0_0_0_1px_var\(--cds-page-bg\)\]:is(:where(.group\/btn):focus-visible *) {
    --tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, var(--cds-page-bg));
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .marker\:text-ink-400 ::marker {
    color: var(--color-ink-400);
  }

  .marker\:text-ink-400::marker {
    color: var(--color-ink-400);
  }

  .marker\:text-ink-400 ::-webkit-details-marker {
    color: var(--color-ink-400);
  }

  .marker\:text-ink-400::-webkit-details-marker {
    color: var(--color-ink-400);
  }

  .file\:mr-2::file-selector-button {
    margin-right: calc(var(--spacing) * 2);
  }

  .file\:rounded::file-selector-button {
    border-radius: .25rem;
  }

  .file\:border-0::file-selector-button {
    border-style: var(--tw-border-style);
    border-width: 0;
  }

  .file\:bg-ink-200::file-selector-button {
    background-color: var(--color-ink-200);
  }

  .file\:px-2::file-selector-button {
    padding-inline: calc(var(--spacing) * 2);
  }

  .file\:py-1::file-selector-button {
    padding-block: var(--spacing);
  }

  .file\:text-\[14px\]::file-selector-button {
    font-size: 14px;
  }

  .file\:text-ink-900::file-selector-button {
    color: var(--color-ink-900);
  }

  .placeholder\:text-ink-400::placeholder {
    color: var(--color-ink-400);
  }

  .first\:mt-0:first-child {
    margin-top: 0;
  }

  .first\:border-t-0:first-child {
    border-top-style: var(--tw-border-style);
    border-top-width: 0;
  }

  .first\:pt-0:first-child {
    padding-top: 0;
  }

  .last\:mb-0:last-child {
    margin-bottom: 0;
  }

  .last\:border-0:last-child {
    border-style: var(--tw-border-style);
    border-width: 0;
  }

  .last\:border-b-0:last-child {
    border-bottom-style: var(--tw-border-style);
    border-bottom-width: 0;
  }

  @media (hover: hover) {
    .hover\:border-beam:hover {
      border-color: var(--color-beam);
    }

    .hover\:border-ink-400:hover {
      border-color: var(--color-ink-400);
    }

    .hover\:border-ink-500:hover {
      border-color: var(--color-ink-500);
    }

    .hover\:bg-ink-050:hover {
      background-color: var(--color-ink-050);
    }

    .hover\:bg-ink-100:hover {
      background-color: var(--color-ink-100);
    }

    .hover\:bg-ink-150:hover {
      background-color: var(--color-ink-150);
    }

    .hover\:bg-ink-600:hover {
      background-color: var(--color-ink-600);
    }

    .hover\:bg-white:hover {
      background-color: var(--color-white);
    }

    .hover\:text-\[color\:var\(--readout-hi\)\]:hover {
      color: var(--readout-hi);
    }

    .hover\:text-beam:hover {
      color: var(--color-beam);
    }

    .hover\:text-ink-600:hover {
      color: var(--color-ink-600);
    }

    .hover\:text-ink-900:hover {
      color: var(--color-ink-900);
    }

    .hover\:underline:hover {
      text-decoration-line: underline;
    }
  }

  .focus\:not-sr-only:focus {
    clip-path: none;
    white-space: normal;
    width: auto;
    height: auto;
    margin: 0;
    padding: 0;
    position: static;
    overflow: visible;
  }

  .focus\:fixed:focus {
    position: fixed;
  }

  .focus\:top-4:focus {
    top: calc(var(--spacing) * 4);
  }

  .focus\:left-4:focus {
    left: calc(var(--spacing) * 4);
  }

  .focus\:z-50:focus {
    z-index: 50;
  }

  .focus\:translate-y-0:focus {
    --tw-translate-y: 0px;
    translate: var(--tw-translate-x) var(--tw-translate-y);
  }

  .focus\:border-ink-400:focus {
    border-color: var(--color-ink-400);
  }

  .focus\:ring-2:focus {
    --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .focus\:ring-beam:focus {
    --tw-ring-color: var(--color-beam);
  }

  .focus\:ring-ink-900:focus {
    --tw-ring-color: var(--color-ink-900);
  }

  .focus\:ring-offset-2:focus {
    --tw-ring-offset-width: 2px;
    --tw-ring-offset-shadow: var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  }

  .focus\:ring-offset-ink-050:focus {
    --tw-ring-offset-color: var(--color-ink-050);
  }

  .focus\:outline-none:focus {
    --tw-outline-style: none;
    outline-style: none;
  }

  .focus-visible\:opacity-100:focus-visible {
    opacity: 1;
  }

  .focus-visible\:outline-hidden:focus-visible {
    --tw-outline-style: none;
    outline-style: none;
  }

  @media (forced-colors: active) {
    .focus-visible\:outline-hidden:focus-visible {
      outline-offset: 2px;
      outline: 2px solid #0000;
    }
  }

  .focus-visible\:outline-2:focus-visible {
    outline-style: var(--tw-outline-style);
    outline-width: 2px;
  }

  .focus-visible\:outline-offset-2:focus-visible {
    outline-offset: 2px;
  }

  .focus-visible\:outline-beam:focus-visible {
    outline-color: var(--color-beam);
  }

  .disabled\:pointer-events-none:disabled {
    pointer-events: none;
  }

  .disabled\:cursor-not-allowed:disabled {
    cursor: not-allowed;
  }

  .disabled\:border:disabled {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }

  .disabled\:border-ink-200:disabled {
    border-color: var(--color-ink-200);
  }

  .disabled\:border-ink-300:disabled {
    border-color: var(--color-ink-300);
  }

  .disabled\:bg-ink-100:disabled {
    background-color: var(--color-ink-100);
  }

  .disabled\:bg-ink-150:disabled {
    background-color: var(--color-ink-150);
  }

  .disabled\:text-ink-400:disabled {
    color: var(--color-ink-400);
  }

  .disabled\:text-ink-600:disabled {
    color: var(--color-ink-600);
  }

  .disabled\:decoration-ink-300:disabled {
    -webkit-text-decoration-color: var(--color-ink-300);
    -webkit-text-decoration-color: var(--color-ink-300);
    text-decoration-color: var(--color-ink-300);
  }

  .disabled\:opacity-40:disabled {
    opacity: .4;
  }

  .disabled\:placeholder\:text-ink-600:disabled::placeholder {
    color: var(--color-ink-600);
  }

  @media (hover: hover) {
    .disabled\:hover\:border-ink-200:disabled:hover {
      border-color: var(--color-ink-200);
    }

    .disabled\:hover\:bg-ink-100:disabled:hover {
      background-color: var(--color-ink-100);
    }

    .disabled\:hover\:bg-ink-150:disabled:hover {
      background-color: var(--color-ink-150);
    }

    .disabled\:hover\:bg-ink-900:disabled:hover {
      background-color: var(--color-ink-900);
    }

    .disabled\:hover\:text-ink-400:disabled:hover {
      color: var(--color-ink-400);
    }

    .disabled\:hover\:text-ink-600:disabled:hover {
      color: var(--color-ink-600);
    }
  }

  .has-\[\:checked\]\:border-beam:has(:checked) {
    border-color: var(--color-beam);
  }

  .has-\[\:checked\]\:ring-1:has(:checked) {
    --tw-ring-shadow: var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
    box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  }

  .has-\[\:checked\]\:ring-beam:has(:checked) {
    --tw-ring-color: var(--color-beam);
  }

  .aria-disabled\:cursor-default[aria-disabled="true"] {
    cursor: default;
  }

  .aria-disabled\:cursor-not-allowed[aria-disabled="true"] {
    cursor: not-allowed;
  }

  .aria-disabled\:border-ink-200[aria-disabled="true"] {
    border-color: var(--color-ink-200);
  }

  .aria-disabled\:bg-ink-100[aria-disabled="true"] {
    background-color: var(--color-ink-100);
  }

  .aria-disabled\:text-ink-400[aria-disabled="true"] {
    color: var(--color-ink-400);
  }

  .aria-pressed\:border-beam[aria-pressed="true"] {
    border-color: var(--color-beam);
  }

  .aria-pressed\:text-ink-900[aria-pressed="true"] {
    color: var(--color-ink-900);
  }

  .data-\[disabled\]\:cursor-default[data-disabled] {
    cursor: default;
  }

  @media (min-width: 40rem) {
    .sm\:col-span-2 {
      grid-column: span 2 / span 2;
    }

    .sm\:mx-0 {
      margin-inline: 0;
    }

    .sm\:inline-flex {
      display: inline-flex;
    }

    .sm\:h-9 {
      height: calc(var(--spacing) * 9);
    }

    .sm\:w-9 {
      width: calc(var(--spacing) * 9);
    }

    .sm\:w-\[132px\] {
      width: 132px;
    }

    .sm\:w-\[160px\] {
      width: 160px;
    }

    .sm\:w-full {
      width: 100%;
    }

    .sm\:min-w-0 {
      min-width: 0;
    }

    .sm\:grid-cols-2 {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .sm\:grid-cols-3 {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .sm\:grid-cols-4 {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .sm\:grid-cols-\[minmax\(0\,0\.82fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .82fr) minmax(0, 1fr);
    }

    .sm\:grid-cols-\[minmax\(0\,1fr\)_auto\] {
      grid-template-columns: minmax(0, 1fr) auto;
    }

    .sm\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,12rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 12rem);
    }

    .sm\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,15rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 15rem);
    }

    .sm\:grid-cols-\[minmax\(0\,2fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    }

    .sm\:grid-cols-\[minmax\(0\,11rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
    }

    .sm\:grid-cols-\[minmax\(0\,13rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
    }

    .sm\:grid-cols-\[minmax\(0\,14rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    }

    .sm\:grid-cols-\[minmax\(0\,auto\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    }

    .sm\:flex-row {
      flex-direction: row;
    }

    .sm\:flex-wrap {
      flex-wrap: wrap;
    }

    .sm\:items-start {
      align-items: flex-start;
    }

    .sm\:gap-3 {
      gap: calc(var(--spacing) * 3);
    }

    .sm\:gap-6 {
      gap: calc(var(--spacing) * 6);
    }

    .sm\:gap-10 {
      gap: calc(var(--spacing) * 10);
    }

    .sm\:gap-x-8 {
      column-gap: calc(var(--spacing) * 8);
    }

    .sm\:border-t-0 {
      border-top-style: var(--tw-border-style);
      border-top-width: 0;
    }

    .sm\:border-r {
      border-right-style: var(--tw-border-style);
      border-right-width: 1px;
    }

    .sm\:border-l {
      border-left-style: var(--tw-border-style);
      border-left-width: 1px;
    }

    .sm\:p-5 {
      padding: calc(var(--spacing) * 5);
    }

    .sm\:p-6 {
      padding: calc(var(--spacing) * 6);
    }

    .sm\:p-7 {
      padding: calc(var(--spacing) * 7);
    }

    .sm\:p-8 {
      padding: calc(var(--spacing) * 8);
    }

    .sm\:px-0 {
      padding-inline: 0;
    }

    .sm\:px-5 {
      padding-inline: calc(var(--spacing) * 5);
    }

    .sm\:px-6 {
      padding-inline: calc(var(--spacing) * 6);
    }

    .sm\:py-10 {
      padding-block: calc(var(--spacing) * 10);
    }

    .sm\:pr-0 {
      padding-right: 0;
    }

    .sm\:pl-0 {
      padding-left: 0;
    }

    .sm\:pl-9 {
      padding-left: calc(var(--spacing) * 9);
    }

    .sm\:text-\[14px\] {
      font-size: 14px;
    }

    .sm\:text-\[34px\] {
      font-size: 34px;
    }

    .sm\:leading-\[36px\] {
      --tw-leading: 36px;
      line-height: 36px;
    }

    .sm\:odd\:border-r:nth-child(odd) {
      border-right-style: var(--tw-border-style);
      border-right-width: 1px;
    }
  }

  @media (min-width: 48rem) {
    .md\:col-span-2 {
      grid-column: span 2 / span 2;
    }

    .md\:mx-0 {
      margin-inline: 0;
    }

    .md\:flex {
      display: flex;
    }

    .md\:grid {
      display: grid;
    }

    .md\:hidden {
      display: none;
    }

    .md\:scroll-mt-20 {
      scroll-margin-top: calc(var(--spacing) * 20);
    }

    .md\:grid-cols-2 {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .md\:grid-cols-3 {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .md\:grid-cols-5 {
      grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .md\:grid-cols-7 {
      grid-template-columns: repeat(7, minmax(0, 1fr));
    }

    .md\:grid-cols-\[1fr_auto_1fr\] {
      grid-template-columns: 1fr auto 1fr;
    }

    .md\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,15rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 15rem);
    }

    .md\:grid-cols-\[minmax\(0\,13rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
    }

    .md\:grid-cols-\[minmax\(14rem\,0\.52fr\)_minmax\(0\,1\.48fr\)\] {
      grid-template-columns: minmax(14rem, .52fr) minmax(0, 1.48fr);
    }

    .md\:items-start {
      align-items: flex-start;
    }

    .md\:border-t-0 {
      border-top-style: var(--tw-border-style);
      border-top-width: 0;
    }

    .md\:border-r {
      border-right-style: var(--tw-border-style);
      border-right-width: 1px;
    }

    .md\:border-b-0 {
      border-bottom-style: var(--tw-border-style);
      border-bottom-width: 0;
    }

    .md\:border-l {
      border-left-style: var(--tw-border-style);
      border-left-width: 1px;
    }

    .md\:px-0 {
      padding-inline: 0;
    }

    .md\:py-0 {
      padding-block: 0;
    }

    .md\:py-14 {
      padding-block: calc(var(--spacing) * 14);
    }

    .md\:py-16 {
      padding-block: calc(var(--spacing) * 16);
    }

    .md\:py-20 {
      padding-block: calc(var(--spacing) * 20);
    }

    .md\:pt-14 {
      padding-top: calc(var(--spacing) * 14);
    }

    .md\:pt-28 {
      padding-top: calc(var(--spacing) * 28);
    }

    .md\:pb-8 {
      padding-bottom: calc(var(--spacing) * 8);
    }
  }

  @media (min-width: 64rem) {
    .lg\:sticky {
      position: sticky;
    }

    .lg\:top-8 {
      top: calc(var(--spacing) * 8);
    }

    .lg\:top-24 {
      top: calc(var(--spacing) * 24);
    }

    .lg\:top-28 {
      top: calc(var(--spacing) * 28);
    }

    .lg\:top-\[76px\] {
      top: 76px;
    }

    .lg\:order-1 {
      order: 1;
    }

    .lg\:order-2 {
      order: 2;
    }

    .lg\:mt-0 {
      margin-top: 0;
    }

    .lg\:mt-3 {
      margin-top: calc(var(--spacing) * 3);
    }

    .lg\:mt-6 {
      margin-top: calc(var(--spacing) * 6);
    }

    .lg\:mb-0 {
      margin-bottom: 0;
    }

    .lg\:block {
      display: block;
    }

    .lg\:grid {
      display: grid;
    }

    .lg\:hidden {
      display: none;
    }

    .lg\:max-h-\[calc\(100vh-8rem\)\] {
      max-height: calc(100vh - 8rem);
    }

    .lg\:max-h-\[calc\(100vh-100px\)\] {
      max-height: calc(100vh - 100px);
    }

    .lg\:w-\[340px\] {
      width: 340px;
    }

    .lg\:max-w-\[17rem\] {
      max-width: 17rem;
    }

    .lg\:max-w-\[1000px\] {
      max-width: 1000px;
    }

    .lg\:shrink-0 {
      flex-shrink: 0;
    }

    .lg\:grid-flow-row {
      grid-auto-flow: row;
    }

    .lg\:grid-cols-2 {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .lg\:grid-cols-3 {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .lg\:grid-cols-4 {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .lg\:grid-cols-5 {
      grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .lg\:grid-cols-\[1fr_auto_1fr_auto_1\.45fr_auto_1fr\] {
      grid-template-columns: 1fr auto 1fr auto 1.45fr auto 1fr;
    }

    .lg\:grid-cols-\[19rem_1fr\] {
      grid-template-columns: 19rem 1fr;
    }

    .lg\:grid-cols-\[184px_minmax\(0\,1fr\)\] {
      grid-template-columns: 184px minmax(0, 1fr);
    }

    .lg\:grid-cols-\[200px_minmax\(0\,1fr\)\] {
      grid-template-columns: 200px minmax(0, 1fr);
    }

    .lg\:grid-cols-\[220px_minmax\(0\,1fr\)\] {
      grid-template-columns: 220px minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,0\.8fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .8fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,0\.55fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .55fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,0\.62fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .62fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,0\.72fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .72fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,0\.85fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,15rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 15rem);
    }

    .lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,18rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 18rem);
    }

    .lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,19rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
    }

    .lg\:grid-cols-\[minmax\(0\,2fr\)_minmax\(0\,1fr\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,15rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,16rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,18rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(0\,420px\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    }

    .lg\:grid-cols-\[minmax\(16rem\,0\.62fr\)_minmax\(0\,1\.38fr\)\] {
      grid-template-columns: minmax(16rem, .62fr) minmax(0, 1.38fr);
    }

    .lg\:grid-rows-1 {
      grid-template-rows: repeat(1, minmax(0, 1fr));
    }

    .lg\:flex-row {
      flex-direction: row;
    }

    .lg\:items-start {
      align-items: flex-start;
    }

    .lg\:justify-between {
      justify-content: space-between;
    }

    .lg\:gap-0\.5 {
      gap: calc(var(--spacing) * .5);
    }

    .lg\:gap-10 {
      gap: calc(var(--spacing) * 10);
    }

    .lg\:gap-12 {
      gap: calc(var(--spacing) * 12);
    }

    .lg\:gap-14 {
      gap: calc(var(--spacing) * 14);
    }

    .lg\:gap-16 {
      gap: calc(var(--spacing) * 16);
    }

    .lg\:gap-x-6 {
      column-gap: calc(var(--spacing) * 6);
    }

    .lg\:gap-x-8 {
      column-gap: calc(var(--spacing) * 8);
    }

    .lg\:gap-x-12 {
      column-gap: calc(var(--spacing) * 12);
    }

    .lg\:self-start {
      align-self: flex-start;
    }

    .lg\:overflow-y-auto {
      overflow-y: auto;
    }

    .lg\:rounded-md {
      border-radius: var(--radius-md);
    }

    .lg\:border-0 {
      border-style: var(--tw-border-style);
      border-width: 0;
    }

    .lg\:border-t-0 {
      border-top-style: var(--tw-border-style);
      border-top-width: 0;
    }

    .lg\:border-r {
      border-right-style: var(--tw-border-style);
      border-right-width: 1px;
    }

    .lg\:border-l {
      border-left-style: var(--tw-border-style);
      border-left-width: 1px;
    }

    .lg\:px-2 {
      padding-inline: calc(var(--spacing) * 2);
    }

    .lg\:py-1\.5 {
      padding-block: calc(var(--spacing) * 1.5);
    }

    .lg\:pt-8 {
      padding-top: calc(var(--spacing) * 8);
    }

    .lg\:pb-10 {
      padding-bottom: calc(var(--spacing) * 10);
    }

    .lg\:first\:pl-0:first-child {
      padding-left: 0;
    }

    .lg\:last\:border-r-0:last-child {
      border-right-style: var(--tw-border-style);
      border-right-width: 0;
    }

    .lg\:last\:pr-0:last-child {
      padding-right: 0;
    }
  }

  @media (min-width: 80rem) {
    .xl\:grid-cols-3 {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .xl\:grid-cols-\[minmax\(0\,1fr\)_236px\] {
      grid-template-columns: minmax(0, 1fr) 236px;
    }

    .xl\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,22rem\)\] {
      grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
    }

    .xl\:grid-cols-\[minmax\(0\,22rem\)_minmax\(0\,1fr\)\] {
      grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
    }

    .xl\:gap-10 {
      gap: calc(var(--spacing) * 10);
    }

    .xl\:rounded-2xl {
      border-radius: var(--radius-2xl);
    }

    .xl\:border-x {
      border-inline-style: var(--tw-border-style);
      border-inline-width: 1px;
    }

    .xl\:pt-8 {
      padding-top: calc(var(--spacing) * 8);
    }
  }

  .\[\&_a\]\:pointer-events-auto a, .\[\&_button\]\:pointer-events-auto button {
    pointer-events: auto;
  }

  .\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker {
    display: none;
  }
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-800-normal-100-0.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
  font-display: block;
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-800-normal-100-1.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-800-normal-100-2.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-900-normal-62-125-0.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 62% 125%;
  unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
  font-display: block;
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-900-normal-62-125-1.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 62% 125%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Archivo;
  src: url("/fonts/archivo-400-900-normal-62-125-2.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 62% 125%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Anybody;
  src: url("/fonts/anybody-400-900-normal-50-150-0.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 50% 150%;
  unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
  font-display: block;
}

@font-face {
  font-family: Anybody;
  src: url("/fonts/anybody-400-900-normal-50-150-1.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 50% 150%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Anybody;
  src: url("/fonts/anybody-400-900-normal-50-150-2.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-stretch: 50% 150%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Bricolage Grotesque;
  src: url("/fonts/bricolage-grotesque-200-800-normal-100-0.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
  font-display: block;
}

@font-face {
  font-family: Bricolage Grotesque;
  src: url("/fonts/bricolage-grotesque-200-800-normal-100-1.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Bricolage Grotesque;
  src: url("/fonts/bricolage-grotesque-200-800-normal-100-2.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Instrument Sans;
  src: url("/fonts/instrument-sans-400-700-normal-100-0.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Instrument Sans;
  src: url("/fonts/instrument-sans-400-700-normal-100-1.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Nunito;
  src: url("/fonts/nunito-400-900-normal-0.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  unicode-range: U+460-52F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
  font-display: block;
}

@font-face {
  font-family: Nunito;
  src: url("/fonts/nunito-400-900-normal-1.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
  font-display: block;
}

@font-face {
  font-family: Nunito;
  src: url("/fonts/nunito-400-900-normal-2.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Nunito;
  src: url("/fonts/nunito-400-900-normal-3.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Martian Mono;
  src: url("/fonts/martian-mono-300-700-normal-100-0.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+460-52F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
  font-display: block;
}

@font-face {
  font-family: Martian Mono;
  src: url("/fonts/martian-mono-300-700-normal-100-1.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display: block;
}

@font-face {
  font-family: Martian Mono;
  src: url("/fonts/martian-mono-300-700-normal-100-2.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-stretch: 100%;
  unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display: block;
}

@font-face {
  font-family: Zodiak;
  src: url("/fonts/zodiak-400-normal-0.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Zodiak;
  src: url("/fonts/zodiak-700-normal-1.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Zodiak;
  src: url("/fonts/zodiak-800-normal-2.woff2") format("woff2");
  font-weight: 800;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Switzer;
  src: url("/fonts/switzer-400-normal-0.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Switzer;
  src: url("/fonts/switzer-500-normal-1.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Switzer;
  src: url("/fonts/switzer-600-normal-2.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Switzer;
  src: url("/fonts/switzer-700-normal-3.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Clash Display;
  src: url("/fonts/clash-display-500-normal-0.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Clash Display;
  src: url("/fonts/clash-display-600-normal-1.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Clash Display;
  src: url("/fonts/clash-display-700-normal-2.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: General Sans;
  src: url("/fonts/general-sans-400-normal-0.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: General Sans;
  src: url("/fonts/general-sans-500-normal-1.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: General Sans;
  src: url("/fonts/general-sans-600-normal-2.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Sentient;
  src: url("/fonts/sentient-400-normal-0.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Sentient;
  src: url("/fonts/sentient-500-normal-1.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Sentient;
  src: url("/fonts/sentient-700-normal-2.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Cabinet Grotesk;
  src: url("/fonts/cabinet-grotesk-400-normal-0.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Cabinet Grotesk;
  src: url("/fonts/cabinet-grotesk-500-normal-1.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: block;
}

@font-face {
  font-family: Cabinet Grotesk;
  src: url("/fonts/cabinet-grotesk-700-normal-2.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: block;
}

.instrument-site {
  --paper: #fbf8f2;
  --paper-raised: #fffdf9;
  --p-ink: #211d15;
  --p-ink-2: #6b6455;
  --p-hairline: #211d1524;
  --p-meta: #767061;
  --frame: #2b2833;
  --frame-2: #37333f;
  --frame-line: #443f4e;
  --readout: #beb8ca;
  --readout-dim: #847d93;
  --readout-hi: #f4f2f8;
  --flag: #d6006e;
  --flag-soft: #e489b6;
  --beam: #0b756f;
  --beam-frame: #22e0d5;
  --note-bg: #f4f2f6;
  --note-line: #dad6e2;
  --color-ink-000: #fbf8f2;
  --color-ink-050: #fffdf9;
  --color-ink-100: #f7f4ec;
  --color-ink-150: #f2eee4;
  --color-ink-200: #e8e3d7;
  --color-ink-300: #d8d2c3;
  --color-ink-400: #767061;
  --color-ink-500: #6f6858;
  --color-ink-600: #6b6455;
  --color-ink-900: #211d15;
  --color-beam: #0b756f;
  --color-flag: #d6006e;
  --font-serif: "Charter", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-mono: "SF Mono", ui-monospace, "Menlo", "Cascadia Mono", monospace;
  background: var(--paper);
  color: var(--p-ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: reduce) {
  .instrument-site *, .instrument-site :before, .instrument-site :after {
    transition: none !important;
    animation: none !important;
  }
}

:root[data-theme="light"] {
  --color-ink-000: #f4f3f6;
  --color-ink-050: #fff;
  --color-ink-100: #fafafc;
  --color-ink-150: #f0eff3;
  --color-ink-200: #e4e2e9;
  --color-ink-300: #d3d0db;
  --color-ink-400: #6b6676;
  --color-ink-500: #605c6b;
  --color-ink-600: #4a4655;
  --color-ink-900: #17151c;
  --color-beam: #0b756f;
  --color-beam-dim: #0b756f24;
  --color-flag: #d6006e;
  --color-judge: #6d5b8f;
  --color-flag-dim: #d1006e1a;
  --color-cleared: #5b7a2e;
  --color-select: #0f9c9438;
  --cursor-write: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='28' fill='none'%3E%3Cpath d='M10 5.5v17' stroke='%231a1c20' stroke-width='1.5'/%3E%3Cpath d='M6.5 4.75h7M6.5 23.25h7' stroke='%230f9c94' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E")
    10 14;
  --fill-flag: #fdebf4;
  --fill-beam: #e8f3f2;
  --fill-judge: #f2eff7;
  --fill-cleared: #f0f4e7;
  --wash-flag: linear-gradient(100deg, #d6006e0e, transparent 46%);
  --wash-judge: linear-gradient(100deg, #6d5b8f12, transparent 46%);
  --wash-beam: linear-gradient(100deg, #0b756f0e, transparent 46%);
  --wash-cleared: linear-gradient(100deg, #5b7a2e0f, transparent 46%);
  color-scheme: light;
}

[data-handle]:after {
  content: "";
  position: absolute;
  inset: -6px;
}

@media (pointer: coarse) {
  [data-handle]:after {
    content: "";
    position: absolute;
    inset: -16px;
  }

  button, [role="button"], summary {
    min-height: 44px;
  }
}

.lightwell [data-el], .lightwell [data-handle], .lightwell [data-img] {
  touch-action: none;
}

.lightwell [data-img] {
  cursor: grab;
}

.lightwell [data-img]:active {
  cursor: grabbing;
}

.lightwell .slide .pad, .lightwell .slide .scrim, .lightwell .slide .bgscrim {
  pointer-events: none;
}

.lightwell .slide [data-el] {
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  *, :before, :after {
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
  }
}

.prose-blog {
  color: var(--color-ink-600);
  overflow-wrap: break-word;
  font-size: 17px;
  line-height: 28px;
}

.prose-blog > * + * {
  margin-top: 20px;
}

.prose-blog h2, .prose-blog h3, .prose-blog h4 {
  color: var(--color-ink-900);
  letter-spacing: -.02em;
  margin-top: 34px;
  font-weight: 700;
  line-height: 1.25;
}

.prose-blog h2 {
  font-size: 24px;
}

.prose-blog h3 {
  font-size: 20px;
}

.prose-blog h4 {
  font-size: 17px;
}

.prose-blog strong {
  color: var(--color-ink-900);
  font-weight: 600;
}

.prose-blog a {
  color: var(--color-beam);
  text-underline-offset: 4px;
  text-decoration: underline;
}

.prose-blog a:hover {
  color: var(--color-ink-900);
}

.prose-blog ul, .prose-blog ol {
  padding-left: 24px;
}

.prose-blog ul {
  list-style: outside;
}

.prose-blog ol {
  list-style: decimal;
}

.prose-blog li + li {
  margin-top: 8px;
}

.prose-blog blockquote {
  border-left: 2px solid var(--color-ink-300);
  color: var(--color-ink-900);
  font-family: var(--font-serif);
  padding: 4px 0 4px 20px;
  font-size: 20px;
  line-height: 30px;
}

.prose-blog code {
  background: var(--color-ink-050);
  border-radius: 4px;
  padding: 2px 5px;
  font-size: 13.5px;
}

.prose-blog pre {
  background: var(--color-ink-050);
  border: 1px solid var(--color-ink-200);
  border-radius: 12px;
  padding: 16px;
  font-size: 13.5px;
  line-height: 22px;
  overflow-x: auto;
}

.prose-blog pre code {
  background: none;
  padding: 0;
}

.prose-blog img {
  border-radius: 12px;
  max-width: 100%;
  height: auto;
}

.prose-blog figure {
  margin-top: 24px;
}

.prose-blog figcaption {
  color: var(--color-ink-400);
  margin-top: 8px;
  font-size: 13.5px;
}

.prose-blog table {
  border-collapse: collapse;
  width: 100%;
  display: block;
  overflow-x: auto;
}

.prose-blog th, .prose-blog td {
  border-bottom: 1px solid var(--color-ink-200);
  text-align: left;
  padding: 8px 12px;
  font-size: 15px;
}

.prose-blog th {
  color: var(--color-ink-900);
}

.prose-blog hr {
  border: 0;
  border-top: 1px solid var(--color-ink-200);
  margin-top: 34px;
}

.studio-room {
  width: 100%;
  min-width: 0;
  height: 100%;
  min-height: 0;
  position: relative;
  overflow: hidden;
}

.studio-room__notice {
  z-index: 80;
  color: #f4f2f8;
  background: #2b2833;
  border: 1px solid #5f586d;
  border-radius: 7px;
  max-width: min(360px, 100% - 64px);
  margin: 0;
  padding: 8px 11px;
  font-size: 12px;
  line-height: 1.35;
  position: absolute;
  top: 52px;
  left: 52px;
  box-shadow: 0 6px 20px #17151c47;
}

[data-canvas-room="limited"] :is(.platecheck, .selread, .studio-composer__send, .seltool button), [data-canvas-room="limited"] .instrument .tools .tool, [data-canvas-room="limited"] .instrument :is(.mmark, .commentmark, .seg button, .skip-link) {
  min-width: 44px;
  min-height: 44px;
}

@media (max-width: 480px) {
  .studio-room__notice {
    max-width: calc(100% - 60px);
    top: 50px;
    left: 50px;
  }
}

.instrument .copy-archived-badge {
  border: 1px solid var(--flag, #a44);
  color: var(--flag, #a44);
  font: 600 9px/1.2 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  vertical-align: middle;
  border-radius: 4px;
  margin-left: 8px;
  padding: 3px 6px;
  display: inline-block;
}

@media (max-width: 900px) {
  .instrument .inspectorpanel {
    border-top: 1px solid var(--note-line);
    border-left: 1px solid var(--note-line);
    width: auto;
    height: min(58vh, 520px);
    max-height: min(58vh, 520px);
    inset: auto 0 42px 38px;
  }

  .instrument .mainpane {
    min-height: 44vh;
  }

  .instrument .console-bar, .instrument .composer, .instrument .studio-composer {
    min-width: 0;
    max-width: 100%;
  }

  .instrument .studio-composer {
    overflow: hidden;
  }

  .instrument .status .aux {
    overflow-wrap: anywhere;
    grid-template-columns: repeat(2, minmax(0, max-content));
    gap: 4px 8px;
    min-width: 0;
    max-width: 100%;
    display: grid;
  }
}

@media (max-width: 480px) {
  .instrument .inspectorpanel {
    height: min(62vh, 480px);
    max-height: min(62vh, 480px);
    left: 38px;
  }

  .instrument .status .aux {
    grid-template-columns: minmax(0, 1fr);
  }

  .instrument .studio-composer :is(input, textarea) {
    text-overflow: ellipsis;
    min-width: 0;
    max-width: calc(100% - 88px);
  }
}

@property --tw-translate-x {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-translate-y {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-translate-z {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-scale-x {
  syntax: "*";
  inherits: false;
  initial-value: 1;
}

@property --tw-scale-y {
  syntax: "*";
  inherits: false;
  initial-value: 1;
}

@property --tw-scale-z {
  syntax: "*";
  inherits: false;
  initial-value: 1;
}

@property --tw-rotate-x {
  syntax: "*";
  inherits: false
}

@property --tw-rotate-y {
  syntax: "*";
  inherits: false
}

@property --tw-rotate-z {
  syntax: "*";
  inherits: false
}

@property --tw-skew-x {
  syntax: "*";
  inherits: false
}

@property --tw-skew-y {
  syntax: "*";
  inherits: false
}

@property --tw-scroll-snap-strictness {
  syntax: "*";
  inherits: false;
  initial-value: proximity;
}

@property --tw-space-y-reverse {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-divide-y-reverse {
  syntax: "*";
  inherits: false;
  initial-value: 0;
}

@property --tw-border-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}

@property --tw-leading {
  syntax: "*";
  inherits: false
}

@property --tw-font-weight {
  syntax: "*";
  inherits: false
}

@property --tw-tracking {
  syntax: "*";
  inherits: false
}

@property --tw-ordinal {
  syntax: "*";
  inherits: false
}

@property --tw-slashed-zero {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-figure {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-spacing {
  syntax: "*";
  inherits: false
}

@property --tw-numeric-fraction {
  syntax: "*";
  inherits: false
}

@property --tw-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-inset-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-inset-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-inset-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-ring-color {
  syntax: "*";
  inherits: false
}

@property --tw-ring-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-inset-ring-color {
  syntax: "*";
  inherits: false
}

@property --tw-inset-ring-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-ring-inset {
  syntax: "*";
  inherits: false
}

@property --tw-ring-offset-width {
  syntax: "<length>";
  inherits: false;
  initial-value: 0;
}

@property --tw-ring-offset-color {
  syntax: "*";
  inherits: false;
  initial-value: #fff;
}

@property --tw-ring-offset-shadow {
  syntax: "*";
  inherits: false;
  initial-value: 0 0 #0000;
}

@property --tw-outline-style {
  syntax: "*";
  inherits: false;
  initial-value: solid;
}

@property --tw-blur {
  syntax: "*";
  inherits: false
}

@property --tw-brightness {
  syntax: "*";
  inherits: false
}

@property --tw-contrast {
  syntax: "*";
  inherits: false
}

@property --tw-grayscale {
  syntax: "*";
  inherits: false
}

@property --tw-hue-rotate {
  syntax: "*";
  inherits: false
}

@property --tw-invert {
  syntax: "*";
  inherits: false
}

@property --tw-opacity {
  syntax: "*";
  inherits: false
}

@property --tw-saturate {
  syntax: "*";
  inherits: false
}

@property --tw-sepia {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow-color {
  syntax: "*";
  inherits: false
}

@property --tw-drop-shadow-alpha {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 100%;
}

@property --tw-drop-shadow-size {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-blur {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-brightness {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-contrast {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-grayscale {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-hue-rotate {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-invert {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-opacity {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-saturate {
  syntax: "*";
  inherits: false
}

@property --tw-backdrop-sepia {
  syntax: "*";
  inherits: false
}

@property --tw-duration {
  syntax: "*";
  inherits: false
}

@property --tw-ease {
  syntax: "*";
  inherits: false
}

@keyframes pulse {
  50% {
    opacity: .5;
  }
}
/*
 * Motion and chrome for the marketing demos.
 *
 * CSS rather than JavaScript wherever the browser can own it: transforms and
 * opacity on the compositor cost nothing, and a keyframe that is declared
 * rather than driven cannot leak a timer. Only the two demos whose state is
 * genuinely discrete — characters typed, frame shown — are driven from rAF.
 *
 * Every animation here ends in the state the element should hold, and none
 * uses `forwards`. That is what makes the reduced-motion block at the bottom a
 * single line: switch the animations off and each element renders at the pose
 * it would have finished in.
 *
 * ---------------------------------------------------------------------------
 * AND THE STUDIO CHROME, WHICH IS THE SECOND HALF OF THIS FILE
 * ---------------------------------------------------------------------------
 *
 * See the header of `StuChrome.tsx` for why a marketing page draws studio
 * chrome by hand at all. What matters here is that every number below was
 * MEASURED off the running product rather than designed: the plate is 46px in
 * `src/editor/bench.css` and `src/design/instrument.css`, its mono is 10.5px at
 * .13em, the capsule is a 9px-radius graphite pill with 4px of padding and
 * 29px buttons, and the squiggle is a 1px wavy underline at 4px offset. A
 * depiction that invents its own metrics is a depiction that will not match the
 * screenshot beside it.
 */

@keyframes demo-caret {
  0%,
  46% {
    opacity: 1;
  }
  50%,
  96% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@keyframes demo-row-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes demo-count {
  0% {
    transform: scale(1);
  }
  38% {
    transform: scale(1.32);
  }
  100% {
    transform: scale(1);
  }
}

@keyframes demo-strike {
  0% {
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

@keyframes demo-fall {
  from {
    opacity: 0;
    transform: translate(var(--dx, 0px), -30px);
  }
  55% {
    opacity: 1;
  }
  to {
    opacity: 1;
    transform: translate(0, 0);
  }
}

@keyframes demo-lane {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}

@keyframes demo-plate {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* The caret sits at the end of the real text, measured from a collapsed Range. */
.demo-caret {
  animation: demo-caret 1.05s steps(1, end) infinite;
}

.demo-row-in {
  animation: demo-row-in 260ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.demo-count {
  display: inline-block;
  animation: demo-count 420ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/*
 * The moment of refusal. Resting state is invisible and the animation carries
 * it in and out — the flash is an event, not a badge, and a ring left on the
 * frame afterwards would say the slide is permanently broken.
 */
.demo-strike {
  opacity: 0;
  animation: demo-strike 900ms ease-out;
}

.demo-lane {
  transform-origin: top center;
  animation: demo-lane 500ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}

/*
 * Chips converge from a common origin into their column — but only once there
 * are columns. Stacked on a phone the horizontal travel is meaningless, and a
 * chip starting 108% of its own width to one side pushed the document wider
 * than the viewport for the length of the animation.
 */
.demo-chip {
  --dx: 0px;
  animation: demo-fall 640ms cubic-bezier(0.2, 0.7, 0.3, 1) var(--delay, 0ms) backwards;
}

@media (width >= 40rem) {
  .demo-chip {
    --dx: var(--dx-column, 0px);
  }
}

.demo-plate {
  animation: demo-plate 420ms cubic-bezier(0.2, 0.7, 0.3, 1) var(--delay, 0ms) backwards;
}

/* Off-screen work is wasted work, and three of these share one page. */
[data-playing='false'] .demo-lane,
[data-playing='false'] .demo-chip,
[data-playing='false'] .demo-plate {
  animation-play-state: paused;
}

/*
 * The caret, when the reader has pressed pause.
 *
 * The rAF clock in `loop.ts` is not the only thing moving in the hero: the
 * caret is a declared `infinite` keyframe that knows nothing about it, so a
 * demo the reader had stopped went on blinking a cursor at them indefinitely.
 * A pause control that leaves something looping misreports what it did.
 *
 * Removed rather than `animation-play-state: paused`, for the same reason the
 * reduced-motion block below removes it: a paused keyframe keeps applying the
 * value it froze on, and half the cycle is `opacity: 0` — so one press in two
 * would have stopped the caret by deleting it. With the animation gone the
 * element renders at its resting pose, which is visible.
 */
[data-playing='false'] .demo-caret {
  animation: none;
}

/*
 * Stopped, not merely slowed.
 *
 * The global rule in index.css crushes durations to 0.01ms, which is the right
 * default but still fires the animation. Here the animation is removed
 * outright, so every element renders at its resting pose and the demos become
 * three still diagrams with the point already made.
 */
@media (prefers-reduced-motion: reduce) {
  .demo-caret,
  .demo-row-in,
  .demo-count,
  .demo-strike,
  .demo-lane,
  .demo-chip,
  .demo-plate,
  .demo-track {
    animation: none !important;
    transition: none !important;
  }

  /* With no flash to carry it, the mark becomes permanent instead: the still
     frame has to say "refused" without a single moving pixel to say it. */
  .demo-strike {
    opacity: 1;
  }
}

/*
 * The swipe track.
 *
 * Transform on a flex row, not scroll position: the frame that is showing is
 * state the demo already holds, and driving a scroller from it would fight the
 * user's own touch scrolling on the page underneath.
 */
.demo-track {
  transition: transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/*
 * The frames at the edge are cut by the viewport, and a hard cut reads as a
 * layout bug rather than as "there is more". Same reasoning as `.edge-cue` in
 * the editor, done with a mask because the strip sits on a panel rather than on
 * the page ground, so a gradient in the page colour would not match.
 */
.demo-viewport {
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    #000 9%,
    #000 91%,
    transparent
  );
  mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}

/*
 * LAYERED, and that is a fix rather than tidiness.
 *
 * These rules are unlayered CSS and Tailwind's utilities live in the
 * `utilities` layer, so `margin: 0` on `.stu-eyebrow` beat every `mt-4` in the
 * markup — unlayered styles win over layered ones whatever the specificity.
 * The visible symptom was a squiggled sentence sitting flush against the label
 * of the next block on `/studios/copy#rewriting`, with no gap at all.
 *
 * `src/marketing/instrument.css` reaches the same conclusion for the same
 * reason and puts its type roles in `@layer components`. Same here: the chrome
 * is components, the spacing in the markup is utilities, and the utilities win.
 */
@layer components {

/* ==========================================================================
   THE STUDIO CHROME, REDUCED
   ==========================================================================
   A faithful reduction of the chrome both studios now wear, drawn at the size
   a marketing column can hold. Sources, and the only sources:

     plate, chip, lens, release, status  ->  src/editor/bench.css §plate, §status
     paper, mk, mmark                    ->  src/design/instrument.css
     capsule chassis                     ->  src/design/calm.css §8 `.c-seltool`

   NOT `@import`ed from those files. `calm.css` alone is 2,000 lines of table,
   rack and rules machinery that no marketing page renders, and it ships inside
   the signed-in shell where the whole of it is used. What is copied here is the
   dozen measurements the reduction actually needs, each named at its rule, so a
   drift is a diff rather than an archaeology exercise.

   THE PALETTE IS LITERAL, exactly as `src/marketing/instrument.css` argues:
   the public face is one material system — warm paper under a graphite frame —
   and it renders the same for everyone. The studios' own dark palette is not
   reproduced here, because a depiction that inverts under a media query is a
   depiction nobody has looked at in the state their reader will get.
   ========================================================================== */

.stu {
  /* Paper and frame, verbatim from `.calm` in src/design/calm.css §1. */
  --stu-paper: #fbf8f2;
  --stu-raised: #fffdf9;
  --stu-ink: #211d15;
  --stu-ink-2: #6b6455;
  /*
   * #767061, NOT the #9A927F the mocks draw and NOT the #9a927f still sitting
   * in `src/marketing/instrument.css`. That value measures 2.92:1 on this
   * paper, which fails AA at body size and fails the 3.0 large-text floor too,
   * so there is no size at which it is legal — and here it would carry readouts
   * at 9–10px, which is the size where a failing ratio stops being a
   * technicality. Darkened along its OWN hue so the paper stays warm: 4.65:1.
   * Computed, not judged — an earlier pass on this codebase tried to fix a
   * failing grey by lightening it and made it worse.
   */
  --stu-meta: #767061;
  --stu-line: #e8e3d7;

  /* The governance instrument. Graphite in both of the product's themes, so
     there is nothing to flip even if this file ever became theme-reactive. */
  --stu-frame: #2b2833;
  --stu-frame-2: #37333f;
  --stu-frame-line: #443f4e;
  --stu-readout: #beb8ca;
  --stu-readout-lo: #9c95ad;
  --stu-readout-hi: #f4f2f8;
  /* The sentence on the bottom plate — bench.css `.status .sentence`. */
  --stu-said: #c9c4d4;

  /* THE ONLY COLOURS WITH MEANING. Owner-locked; the pink is the signature. */
  --stu-flag: #d6006e;
  --stu-flag-soft: #e489b6;
  --stu-beam: #0b756f;
  --stu-beam-frame: #22e0d5;

  /*
   * WHAT SELECTION LOOKS LIKE ON PAPER, as one number.
   *
   * A beam tint, and it has to stay this faint for a measured reason: the meta
   * grey rides at 4.85:1 on the raised card, and a 0.09 tint drags it to 4.11
   * — under AA at the 9px this label is set at. Three surfaces wear it (a
   * format card, an axis row, a type specimen) and they were three separate
   * literals, so the first one anybody deepened would have failed alone and
   * silently. One token, checked once, by `contrast-live` against the real DOM.
   */
  --stu-pick: rgba(11, 117, 111, 0.04);

  --stu-mono: 'SF Mono', ui-monospace, 'Menlo', 'Cascadia Mono', monospace;
  --stu-serif: 'Charter', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;

  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: 12px;
  background: var(--stu-paper);
  color: var(--stu-ink);
  border: 1px solid var(--stu-line);
  box-shadow: 0 24px 60px -30px rgba(23, 21, 28, 0.55);
}

/* ---------- the graphite plate ------------------------------------------ */
/*
 * bench.css `.plate`: 46px tall, mono 10.5px at .13em, uppercase, 0 14px 0 18px.
 * Reduced to 34px and 9.5px because the product's plate spans a 1440px window
 * and this one spans a 340–560px column — holding 46px here would make the
 * chrome half the drawing. Everything that is not a size is unchanged.
 */
.stu-plate {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 34px;
  padding: 0 8px 0 11px;
  background: var(--stu-frame);
  color: var(--stu-readout);
  font-family: var(--stu-mono);
  font-size: 9.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.stu-crumb {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
}

/*
 * THE BRAND HOLDS AND THE DOCUMENT'S NAME TRUNCATES, which is the way round the
 * product does it and the opposite of what this first shipped as. Measured on
 * the running Copy Studio at 1440: the plate reads "NORTHWIND DERMATOLOGY ·
 * Veltriva HCP ema…". Getting it backwards collapsed the brand to "N…" in the
 * narrower bands and left the plate naming nothing a reader could place.
 */
.stu-brand {
  flex: none;
}

/* The brand's mark. `.plate .crumb i` — the one beam-coloured pixel up here. */
.stu-crumb i {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 2px;
  background: var(--stu-beam-frame);
}

/* The document's own name. Mixed case on purpose: it is the customer's title,
   not a governance label, and `.plate .crumb b` un-shouts it in the product. */
.stu-doc {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--stu-readout-hi);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
}

.stu-rhs {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 7px;
}

/* bench.css `.chip` — the status pill. Never wraps: a two-line chip inside a
   34px plate is a broken plate, which is the product's own note at its rule. */
.stu-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: none;
  border: 1px solid var(--stu-frame-line);
  border-radius: 999px;
  padding: 2.5px 8px;
  font-size: 9px;
  letter-spacing: 0.11em;
  white-space: nowrap;
  color: var(--stu-readout);
}

.stu-chip i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--stu-readout-lo);
  flex: none;
}

.stu-chip.flag {
  color: #ff9ac8;
  border-color: #7a2b55;
}
.stu-chip.flag i {
  background: var(--stu-flag);
}
.stu-chip.soft {
  color: #e9b7cf;
  border-color: #5e4053;
}
.stu-chip.soft i {
  background: none;
  border: 1.5px solid var(--stu-flag-soft);
}
.stu-chip.clear {
  color: var(--stu-beam-frame);
  border-color: #1e5c58;
}
.stu-chip.clear i {
  background: var(--stu-beam-frame);
}

/*
 * The channel marks — bench.css `.lens`.
 *
 * THE BENCH HAS THESE AND COPY STUDIO DOES NOT, and that asymmetry is a claim
 * rather than an oversight in the drawing: `copy_documents` carries no platform
 * column, so a channel mark over a letter would be the depiction asserting
 * something the product cannot know.
 */
.stu-lens {
  display: flex;
  flex: none;
  border: 1px solid var(--stu-frame-line);
  border-radius: 5px;
  overflow: hidden;
}

.stu-lens span {
  width: 22px;
  height: 19px;
  display: grid;
  place-items: center;
  color: var(--stu-readout-lo);
}

.stu-lens span.on {
  background: var(--stu-frame-2);
  color: var(--stu-beam-frame);
}

/*
 * Undo and redo. Dim, because on a deck nobody has touched yet there is nothing
 * to undo — which is the state the product opens in.
 *
 * 0.8, COMPUTED. It was 0.55, which composites #9C95AD over #2B2833 to #696476
 * and 2.53:1 — under the 3:1 that 1.4.11 asks of a meaningful graphic even
 * where the control it depicts is inactive, and visibly a pair of smudges. 0.8
 * gives #857F95 at 3.76:1: still clearly the quiet end of the plate, still
 * legible as two arrows.
 */
.stu-hist {
  display: flex;
  gap: 1px;
  flex: none;
  color: var(--stu-readout-lo);
  opacity: 0.8;
}

.stu-hist span {
  width: 19px;
  height: 19px;
  display: grid;
  place-items: center;
}

/* bench.css `.release`, and Copy Studio's `.signoff`. */
.stu-rel {
  flex: none;
  border: 1px solid var(--stu-frame-line);
  border-radius: 5px;
  padding: 3.5px 8px;
  color: var(--stu-readout-hi);
  font-size: 9.5px;
  letter-spacing: 0.13em;
  white-space: nowrap;
}

/* The verb that is currently the one to press. Teal, as CHECK is in the
   product — the beam is affirmation, and it is the only other colour up here. */
.stu-rel.earned {
  color: var(--stu-beam-frame);
  border-color: #1e5c58;
}

/* Not available yet. `.release[aria-disabled]` is opacity .34 in the product;
   at 9.5px on graphite that is unreadable, so this dims by hue, not by alpha. */
.stu-rel.spent {
  color: var(--stu-readout-lo);
  border-color: #35313f;
}

.stu-dots {
  flex: none;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  color: var(--stu-readout);
  letter-spacing: 0;
}

/* ---------- the grounds ------------------------------------------------- */

.stu-paper {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--stu-paper);
}

/* The stage the Bench floats a frame on — bench.css `.stage`. Not paper: the
   artwork IS paper, and a paper frame on a paper ground has no edge. */
.stu-stage {
  flex: 1 1 auto;
  min-width: 0;
  background: linear-gradient(180deg, #bdb7cd, #b4aec6);
}

/* ---------- the signature mark ------------------------------------------ */
/*
 * instrument.css `.mk`: a 1px wavy underline 4px under the words, full tone for
 * a rule a machine settled, soft tone for one only a person can settle.
 *
 * THERE ARE THREE MARKS IN THE PRODUCT, NOT TWO, and this site was drawing the
 * wrong one for the middle case. `instrument.css` sets:
 *
 *   .mk.stop.on              wavy, --flag        a rule a machine settled
 *   .mk.hold.on              wavy, --flag-soft   a rule only a person can settle
 *   .mk[data-kind='judge']   beam BRACKETS       a model's opinion, not a match
 *
 * The brackets are alive and they mean the third thing. The site used them for
 * the second, which is the substitution `instrument.css` calls "the worst mark
 * this product can make" at its own rule: drawing a model's opinion with the
 * geometry of a matched pattern. So "needs a person" is drawn here as what it
 * actually is — the same squiggle, softer — and one gesture in two tones is
 * also the better argument, because it says the two findings are the same kind
 * of object seen at two strengths, which is exactly what they are.
 *
 * Measured off the running product rather than read off the stylesheet:
 * `.mk.hold.on` computes to `text-decoration-color: rgb(228, 137, 182)`, wavy,
 * 1px thick, 4px offset.
 */
.stu-mk {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: transparent;
  transition: text-decoration-color 0.24s ease-out;
}

.stu-mk.stop.on {
  text-decoration-color: var(--stu-flag);
}

.stu-mk.hold.on {
  text-decoration-color: var(--stu-flag-soft);
}

/* The gutter mark — instrument.css `.mmark`. One short rule in the margin, the
   same gesture as the squiggle, so a finding is findable without reading. */
.stu-mmark {
  display: block;
  width: 18px;
  height: 0;
  border-top: 2px solid var(--stu-flag);
}

.stu-mmark.hold {
  border-top-color: var(--stu-flag-soft);
}

/* ---------- the selection capsule --------------------------------------- */
/*
 * ONE CHASSIS, STUDIO CARGO — calm.css §8 `.c-seltool`, reduced.
 *
 * Graphite ground, 9px radius, 4px padding, 2px gap, 29px buttons, and a 1px
 * 16px separator with 4px either side. Those six numbers ARE the object; both
 * studios wear them unchanged and so does the platform's bulk bar. The buttons
 * are drawn at 24px here for the same reason the plate is 34px — the column is
 * a third of the product's width — and the ratios are held, so the thing still
 * reads as the same pill.
 *
 * The verb ORDER is the shared contract and it is the half worth depicting:
 * co-reader first, then formatting, then the studio's own verbs, then ⋯. A
 * finding on the selection leads the whole bar, because a thing that stops a
 * release outranks a thing that changes a word.
 */
.stu-cap {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: var(--stu-frame);
  border-radius: 9px;
  padding: 4px;
  box-shadow:
    0 3px 8px rgba(23, 21, 28, 0.2),
    0 12px 34px rgba(23, 21, 28, 0.3);
}

.stu-cap span.v {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  color: #c9c4d4;
  font-family: var(--stu-serif);
  font-size: 13px;
  line-height: 1;
  flex: none;
}

/* The finding verb. Chassis-identical; the pink is the signature mark's own,
   and bench.css is explicit that it is the only colour the bar carries. */
.stu-cap span.v.why {
  color: #ff9ac8;
}

.stu-cap span.sep {
  width: 1px;
  height: 14px;
  margin: 0 3px;
  background: var(--stu-frame-line);
  flex: none;
}

/* The type-size stepper — a canvas verb with no counterpart in a writing
   surface, so the Bench assembles it out of the chassis's own button. */
.stu-cap span.val {
  font-family: var(--stu-mono);
  font-size: 9px;
  color: var(--stu-readout-lo);
  min-width: 30px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------- the bottom plate -------------------------------------------- */
/*
 * bench.css `.status` and Copy Studio's `.status`, which are the same object:
 * one grammatical sentence about what the screen currently says, and a mono
 * readout of what is true. The sentence is mono in sentence case with almost no
 * tracking; the readout is mono at 9.5px, .11em, uppercase. That difference is
 * doing work — the sentence is the instrument speaking and the readout is the
 * record, and shouting both would flatten them into one voice.
 */
.stu-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 32px;
  padding: 7px 11px;
  background: var(--stu-frame);
  border-top: 1px solid #17151c;
  font-family: var(--stu-mono);
}

/*
 * ONE LINE, ALWAYS. The product's plate is a fixed 44px and its sentence never
 * wraps; wrapped to two lines here it stopped reading as a plate and started
 * reading as a paragraph in a dark box. Truncated rather than shrunk, because
 * the opening clause — "One thing stops a release" — is the whole claim and it
 * survives any truncation that leaves the plate its width.
 */
.stu-said {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 10.5px;
  letter-spacing: 0.01em;
  color: var(--stu-said);
}

.stu-said i {
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--stu-beam-frame);
  opacity: 0;
  transition: opacity 0.24s ease-out;
}

/* Reading, not read. The product breathes this dot while a check is in flight
   and holds it lit once the check has landed. */
.stu-said.reading i {
  opacity: 1;
  animation: demo-breathe 1.2s ease-in-out infinite;
}

.stu-said.done i {
  opacity: 1;
}

@keyframes demo-breathe {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}

.stu-read {
  margin-left: auto;
  font-size: 9px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--stu-readout-lo);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/*
 * The readout is the first thing to go when the column runs out, and that is
 * the right order: the sentence is the claim and the readout is its receipt.
 * Hidden rather than wrapped — bench.css refuses a two-line plate for the same
 * reason — and a phone reader keeps the sentence, which is the half that argues.
 */
@media (width < 30rem) {
  .stu-read {
    display: none;
  }
}

/* Off-screen work is wasted work; the same gate the rest of this file uses. */
[data-playing='false'] .stu-said.reading i {
  animation-play-state: paused;
}

/* ---------- what the plate drops when the column runs out ---------------- */
/*
 * At 342px — a 390px phone inside the site's `max-w-[1180px] px-6` container —
 * a plate carrying a chip, channel marks, undo, redo, a release verb and ⋯
 * leaves the document's own name about four characters. The product's plate
 * never faces this width; the depiction does, on the traffic that matters most.
 *
 * So the plate sheds in order of how much each part argues. The channel marks,
 * the history pair and the revision count go; the status chip, the release verb
 * and the name of the thing being worked on stay, because those three are the
 * claim. Nothing here is hidden on the desktop layout, so a reader on a laptop
 * still sees the whole plate the product draws.
 */
@media (width < 30rem) {
  .stu-opt {
    display: none;
  }
}

/* ---------- the writing surface ----------------------------------------- */

/*
 * THE MEASURE, held in the padding rather than in a wrapper.
 *
 * `instrument.css` sets `.sheet { max-width: 620px }` inside a paper column
 * that is far wider, and that is not a detail: a document set to the full width
 * of a 1740px band is not a document anybody would write in, and the depiction
 * would be granting itself a comfort the product does not have. Doing it with
 * `max()` on the inline padding centres the same measure without every screen
 * in this folder having to grow an extra div, and it degrades correctly — below
 * 620px the `14px` wins and the sheet simply fills the column.
 */
.stu-sheet {
  padding: 16px max(14px, calc((100% - 620px) / 2)) 20px;
}

/* The sheet and its margin, which is where a finding shows up before you have
   read a word of it — `instrument.css` puts the marks rail outside the text. */
.stu-line-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.stu-gutter {
  flex: none;
  width: 18px;
  padding-top: 0.72em;
}

/*
 * The document's own words.
 *
 * SANS, and that is measured rather than assumed. The brief for this pass said
 * "serif for content", and the running Copy Studio sets its blocks in
 * `Avenir Next 22px/34px` — the serif in this system is reserved for a RULE
 * speaking, which is `.stu-rule` below. `marketing/instrument.css` reaches the
 * same conclusion from the mock: the only serif in the whole of Direction B is
 * the quoted regulation in the margin.
 */
.stu-body {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--stu-ink);
}

/* The caret sits at the end of the real text, and stops when the reader has. */
.stu-caret {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--stu-beam);
  animation: demo-caret 1.05s steps(1, end) infinite;
}

[data-playing='false'] .stu-caret {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .stu-caret {
    animation: none !important;
  }
}

/* ---------- the paper, the rail, and the console ------------------------ */
/*
 * `instrument.css` `.work` is `paper | divider | agent`, and Copy Studio docks
 * the findings there. The rail collapses under the paper below 48rem rather
 * than beside it, which is what the product does at its own narrow end.
 */
.stu-work {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  background: var(--stu-paper);
}

@media (width >= 48rem) {
  .stu-work {
    grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
  }
}

.stu-rail {
  min-width: 0;
  padding: 14px 14px 16px;
  background: #f4f2f6;
  border-top: 1px solid var(--stu-line);
}

@media (width >= 48rem) {
  .stu-rail {
    border-top: 0;
    border-left: 1px solid var(--stu-line);
  }
}

/* Mono, because the panel is naming a governance surface rather than titling a
   piece of writing. `.instrument .panehead` does the same. */
.stu-railhead {
  margin: 0 0 9px;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stu-ink-2);
}

.stu-rail .stu-note {
  margin-top: 0;
}

/* The console — `instrument.css` `.console-bar`, which is part of the fascia
   rather than of the paper, so it can never cover the words. */
.stu-console {
  flex: none;
  display: flex;
  justify-content: center;
  padding: 8px 14px 12px;
  background: var(--stu-paper);
}

/* `calm.css` `.c-capsule`: the studio's only text-input shape. */
.stu-composer {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  max-width: 30rem;
  width: 100%;
  background: var(--stu-raised);
  border: 1px solid #dad6e2;
  border-radius: 999px;
  padding: 5px 5px 5px 12px;
  box-shadow: 0 6px 18px -12px rgba(23, 21, 28, 0.5);
}

/* The nib. One beam-coloured mark, matching the plate's brand dot in weight. */
.stu-composer > i {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50% 50% 50% 2px;
  background: var(--stu-beam);
}

.stu-composer .stu-placeholder {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  color: var(--stu-ink-2);
}

.stu-khint {
  flex: none;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--stu-ink-2);
}

.stu-composer > b {
  flex: none;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--stu-frame);
  color: #fff;
  font-size: 11px;
  font-weight: 400;
}

/* ---------- the finding note -------------------------------------------- */
/*
 * `BenchFnote` and Copy Studio's rules panel are the same card: where the
 * finding came from, what it does, the rule, and what can be done about it.
 * The order is the argument — provenance BEFORE severity, because "a machine
 * matched this" and "a model thinks this" are different enough that a reader
 * who skips the first line has misread the second.
 */
.stu-note {
  margin-top: 16px;
  border: 1px solid var(--stu-line);
  border-radius: 9px;
  background: var(--stu-raised);
  padding: 11px 13px 12px;
}

.stu-prov {
  margin: 0;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--stu-meta);
}

/* `.fnote h4.stop` — the pink is the signature's, and it is the only colour
   this card carries. */
.stu-notehead {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--stu-flag);
}

/* THE SERIF, and the one place on this drawing that earns it: a rule speaking.
   `bench.css` says so at `.fnote .rule` and it is the same decision here. */
.stu-rule {
  margin: 5px 0 0;
  font-family: var(--stu-serif);
  font-size: 14px;
  line-height: 1.4;
  color: var(--stu-ink);
}

.stu-said-note {
  margin: 5px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--stu-ink-2);
}

.stu-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
}

.stu-acts span {
  border: 1px solid var(--stu-line);
  border-radius: 7px;
  padding: 4px 9px;
  font-size: 12px;
  color: var(--stu-ink);
  background: var(--stu-paper);
}

/* ---------- the format gallery ------------------------------------------ */

.stu-eyebrow {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--stu-meta);
}

.stu-quiet {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--stu-ink-2);
}

.stu-card {
  border: 1px solid var(--stu-line);
  border-radius: 8px;
  padding: 8px 9px 9px;
  transition:
    border-color 0.3s ease-out,
    background-color 0.3s ease-out;
}

/* A frame drawn as a frame. Filled, for the reason at the call site. */
.stu-frame-pip {
  display: block;
  width: 11px;
  height: 15px;
  border-radius: 2px;
  border: 1px solid #d8d2c3;
  background: #e6e0d1;
  flex: none;
}

.stu-cardname {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--stu-ink);
}

/*
 * `--stu-ink-2`, NOT `--stu-meta`, and this is the selection tint's bill.
 *
 * The meta grey is 4.85:1 on the raised card and 4.40:1 once `--stu-pick` is
 * laid over it — measured against the real DOM, not estimated. Two ways out:
 * make the selection invisible, or make the label a step darker everywhere.
 * The second is better on its own terms as well as legally, because a selected
 * row's own text getting slightly stronger is what selection ought to look
 * like. 5.9:1 unpicked, 5.3:1 picked, and still plainly the recessive line.
 */
.stu-cardwhere {
  margin: 1px 0 0;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stu-ink-2);
}

.stu-declares {
  border: 1px solid var(--stu-ink);
  border-radius: 9px;
  padding: 10px 11px 11px;
}

.stu-role {
  border: 1px solid rgba(11, 117, 111, 0.45);
  border-radius: 6px;
  padding: 2px 7px;
  font-size: 11.5px;
  color: var(--stu-ink);
}

/* ---------- the Bench's stage, frame and strip -------------------------- */

.stu-stage {
  display: flex;
  justify-content: center;
  padding: 14px 12px 16px;
}

/*
 * The easel: the frame, and the note that opens beside it.
 *
 * Wraps rather than shrinks. In the product the note is placed by `placeFnote`,
 * which has three answers — right margin, left margin, or stacked under the
 * anchor when there is no margin left — and the third is exactly what a
 * narrow column here should get. Wrapping reproduces that placement rule
 * without reproducing its geometry.
 */
/*
 * `width: 100%` is load-bearing. A wrapping flex container's max-content width
 * is the widest single LINE, not the sum of its items — so left to size itself
 * the easel resolved to 562px, decided its two 320px+292px children could not
 * share a line, and wrapped them at a viewport with 880px of room. Measured,
 * not reasoned about: `.stu-easel: 562x642` while `.stu-stage: 880`.
 */
.stu-easel {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 14px;
  width: 100%;
  min-width: 0;
}

.stu-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 0 1 320px;
}

.stu-fnote {
  margin-top: 0;
  flex: 0 1 292px;
  min-width: 0;
  /* The note is a panel over the stage, so it carries the product's own
     `.fnote` lift rather than sitting flat like a card on paper. */
  box-shadow: 0 10px 30px -18px rgba(23, 21, 28, 0.6);
}

/* `.fnote .nowording` — mono, because the absence of a supplied wording is a
   fact about the rule rather than a sentence the instrument is speaking. */
.stu-nowording {
  margin: 8px 0 0;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  color: var(--stu-ink-2);
}

/*
 * The selected element, as the canvas draws it: a beam outline with a handle at
 * each corner. Drawn with a shadow-spread ring plus four small squares rather
 * than an outline and four elements, so it adds one box to the tree.
 */
/*
 * The element the capsule is acting on. The auto margin lives HERE rather than
 * on `.stu-head`, because wrapping the headline moved the flex child down a
 * level and the headline's `margin-top: auto` stopped reaching the canvas —
 * which pinned the type to the top of the frame instead of resting it above the
 * footer. Caught in the side-by-side, not by any test.
 */
.stu-elbox {
  margin-top: auto;
  min-width: 0;
}

.stu-sel {
  position: relative;
  outline: 1px solid var(--stu-beam);
  outline-offset: 5px;
}

.stu-sel::before,
.stu-sel::after {
  content: '';
  position: absolute;
  width: 5px;
  height: 5px;
  background: var(--stu-beam);
  pointer-events: none;
}

.stu-sel::before {
  left: -8px;
  top: -8px;
  box-shadow: calc(100% + 11px) 0 0 var(--stu-beam);
}

.stu-sel::after {
  left: -8px;
  bottom: -8px;
  box-shadow: calc(100% + 11px) 0 0 var(--stu-beam);
}

.stu-frame {
  display: flex;
  align-items: stretch;
  width: 100%;
  max-width: 320px;
  min-width: 0;
}

/*
 * The spine — the deck itself, as an object you can select.
 * `bench.css` `.spine`: 19px wide, graphite, its label set vertically in mono
 * at .28em. It is the rung above "frame" on the selection ladder, and drawing
 * the stage without it would lose the one affordance that says a deck is a
 * thing and not just a pile of frames.
 */
.stu-spine {
  flex: none;
  width: 15px;
  border-radius: 4px 0 0 4px;
  background: linear-gradient(90deg, var(--stu-frame-line), var(--stu-frame-2) 55%, var(--stu-frame));
  color: #a79fbc;
  font-family: var(--stu-mono);
  font-size: 7px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  display: grid;
  place-items: center;
  padding: 8px 0;
}

.stu-art {
  flex: 1 1 auto;
  min-width: 0;
  aspect-ratio: 4 / 5;
  background: #f6f3ea;
  border: 1px solid rgba(33, 29, 21, 0.16);
  display: flex;
  flex-direction: column;
  padding: 12px 13px 11px;
  position: relative;
}

/* 0.62 rather than 0.5: composited on the artwork's #F6F3EA that is 4.57:1
   against 3.18:1, and this is 8px mono — the size where a failing ratio stops
   being a technicality. */
.stu-artnum {
  align-self: flex-end;
  font-family: var(--stu-mono);
  font-size: 8px;
  letter-spacing: 0.1em;
  color: rgba(33, 29, 21, 0.62);
}

/*
 * The frame's own typography, which is the customer's brand rather than this
 * site's. Serif, because the deck in the product's own preview fixture is set
 * in the `broadsheet` pairing and that is what a reader will see if they open
 * it. Not the site's serif role — the site's rules happen to agree here.
 */
/*
 * `line-height: 1.24`, and this is the squiggle's constraint rather than a
 * typographic preference. A wavy underline sits 4px under its own baseline; at
 * the 1.06 leading a display headline wants, the mark under line one lands on
 * top of line two and the signature reads as a rendering fault. The Bench has
 * the same tension and resolves it the same way — `slide.css` sets
 * `text-underline-offset: .14em` on a flagged field precisely so the mark stays
 * inside its own line box.
 */
.stu-head {
  margin: 0;
  font-family: var(--stu-serif);
  font-size: clamp(15px, 4.6cqw, 21px);
  line-height: 1.24;
  letter-spacing: -0.015em;
  color: #17150f;
}

.stu-head .stu-mk {
  text-underline-offset: 0.14em;
}

.stu-headsm {
  margin: 0;
  font-size: 11px;
  line-height: 1.3;
  color: rgba(33, 29, 21, 0.66);
  max-width: 20ch;
}

.stu-stat {
  margin: auto 0 0;
  font-family: var(--stu-serif);
  font-size: clamp(38px, 15cqw, 62px);
  line-height: 0.82;
  letter-spacing: -0.04em;
  color: #17150f;
}

.stu-artnote {
  margin: 7px 0 0;
  font-size: 10px;
  line-height: 1.35;
  color: rgba(33, 29, 21, 0.62);
}

.stu-artfoot {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin: auto 0 0;
  padding-top: 10px;
  font-size: 9px;
  font-weight: 600;
  color: rgba(33, 29, 21, 0.72);
}

/* Container query units above: the headline has to hold its proportion inside a
   frame that is 224px on a laptop and 150px on a phone, and `vw` would size it
   against the viewport instead. */
.stu-frame {
  container-type: inline-size;
}

/* The strip — `bench.css` `.strip`, on the plate's own graphite. */
.stu-strip {
  flex: none;
  background: var(--stu-frame);
  padding: 9px 11px 8px;
}

.stu-striphead {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  font-family: var(--stu-mono);
  font-size: 8px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stu-readout-lo);
}

/* The right half of the strip's header explains the bars. It is the first
   thing to go: the bars are legible without it and the label is not. */
@media (width < 30rem) {
  .stu-stripaside {
    display: none;
  }
}

/*
 * The beats are FIXED WIDTH and left-aligned, not a stretched row.
 *
 * `bench.css` gives a beat 68px standing and the strip fills leftward from the
 * first frame — the deck is a sequence with a beginning, and stretching five
 * bars across 1700px turns that sequence into a chart. Measured against the
 * running Bench: five thumbs and a caption occupy the left quarter of a 1440px
 * strip, and the empty right-hand side is where the deck would grow.
 */
.stu-beats {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  margin-top: 8px;
}

.stu-beat {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 3px;
  flex: none;
  width: 44px;
}

/* The caption is not a frame, so it is set off rather than lined up with them
   — the product puts a `.stripsep` hairline in this exact place. */
.stu-beat.cap {
  margin-left: 10px;
  padding-left: 12px;
  border-left: 1px solid var(--stu-frame-line);
  box-sizing: content-box;
}

/*
 * Narrower beats where the column cannot hold six.
 *
 * At a 320px viewport the caption beat ran off the end of the strip and was
 * silently clipped by `.stu` — the document did not overflow, so nothing
 * flagged it, and the depiction just quietly stopped mentioning that a deck has
 * a caption. Found by walking every box against the viewport edge rather than
 * by reading `scrollWidth`, which is the check that would have missed it.
 *
 * Narrowed rather than scrolled: `Layout.tsx` makes the point that a scroll
 * container with no focusable child is not in Chrome's tab order, and six bars
 * that fit need none of that machinery.
 */
@media (width < 26rem) {
  .stu-beat {
    width: 30px;
  }

  .stu-beat.cap {
    margin-left: 6px;
    padding-left: 8px;
  }
}

/*
 * #767091, computed: 3.09:1 on the strip's graphite, which is what 1.4.11 asks
 * of a graphic that carries information — and these bars carry the one thing
 * the strip is for, the number of words on each frame. It started at #4D4760,
 * lifted straight off the Bench's own thumbnails, and measured 1.64:1. The
 * product gets away with that because its beats are picture thumbnails with
 * their own contrast; a flat bar has only its fill.
 */
.stu-beat i {
  display: block;
  border-radius: 2px;
  background: #767091;
  transition: background-color 0.3s ease-out;
}

.stu-beat i.on {
  background: var(--stu-readout-hi);
}

.stu-beat.cap i {
  background: none;
  border: 1px solid var(--stu-frame-line);
}

.stu-beat em {
  font-family: var(--stu-mono);
  font-size: 7.5px;
  font-style: normal;
  letter-spacing: 0.1em;
  color: var(--stu-readout-lo);
}

/* ---------- the plate's revision count and variant chips ---------------- */

.stu-rev {
  color: var(--stu-readout-lo);
  white-space: nowrap;
}

/* `.varchip` — one per sibling document, lettered, in the plate. The chips are
   where the product puts them because the placement IS the feature: a variant
   is another document you are one click from, not a copy filed somewhere. */
.stu-varchips {
  display: flex;
  gap: 3px;
  flex: none;
}

.stu-varchips span {
  width: 17px;
  height: 17px;
  display: grid;
  place-items: center;
  border: 1px solid var(--stu-frame-line);
  border-radius: 4px;
  font-size: 9px;
  color: var(--stu-readout-lo);
}

.stu-varchips span.on {
  color: var(--stu-beam-frame);
  border-color: #1e5c58;
  background: var(--stu-frame-2);
}

/* ---------- rows, cards and candidates on paper ------------------------- */

.stu-cand {
  border: 1px solid var(--stu-line);
  border-radius: 8px;
  background: var(--stu-raised);
  padding: 8px 10px 9px;
  transition:
    opacity 0.5s ease-out,
    transform 0.5s ease-out,
    border-color 0.5s ease-out;
}

/* The verdict. Sans and sentence case rather than shouted mono: mono here is
   reserved for the record talking, and a verdict is the instrument talking. */
.stu-verdict {
  margin: 0;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* The candidate wording — the customer's own words being tested, so serif. */
.stu-candtext {
  margin: 3px 0 0;
  font-family: var(--stu-serif);
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--stu-ink);
}

.stu-rowcard {
  border: 1px solid var(--stu-line);
  border-radius: 8px;
  background: var(--stu-raised);
  padding: 7px 10px 8px;
  transition:
    opacity 0.5s ease-out,
    transform 0.5s ease-out,
    border-color 0.5s ease-out;
}

.stu-rowcard.dashed {
  border-style: dashed;
  background: none;
}

/* The revision's identity. Mono, because a revision number IS the record. */
.stu-revtag {
  flex: none;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--stu-meta);
}

.stu-rowtext {
  min-width: 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--stu-ink);
}

.stu-approved {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--stu-ink-2);
}

.stu-approved b {
  color: var(--stu-beam);
  font-weight: 600;
}

.stu-door {
  border: 1px solid var(--stu-line);
  border-radius: 8px;
  background: var(--stu-raised);
  padding: 9px 11px 10px;
}

.stu-door .stu-cardname {
  margin-top: 0;
}

/* ---------- the layout and composition axes ----------------------------- */

.stu-shapeart {
  position: relative;
  margin: 0 auto;
  aspect-ratio: 4 / 5;
  width: 100%;
  max-width: 13rem;
  min-width: 0;
  overflow: hidden;
  border-radius: 6px;
  border: 1px solid var(--stu-line);
  background: var(--stu-raised);
}

.stu-shapename {
  margin: 5px 0 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--stu-ink);
}

.stu-shapename .stu-dot {
  color: var(--stu-meta);
}

.stu-axisrow {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 12.5px;
  color: var(--stu-ink);
  transition: background-color 0.3s ease-out;
}

/* Same reasoning as `.stu-cardwhere`: this label sits under `--stu-pick` on the
   selected row, and the meta grey does not clear AA there. */
.stu-axismeta {
  color: var(--stu-ink-2);
}

.stu-specimen {
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 15px;
  transition: background-color 0.3s ease-out;
}

.stu-swatch {
  display: block;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  border: 1px solid var(--stu-line);
  transition: transform 0.3s ease-out;
}

/* ---------- the release ceremony ---------------------------------------- */
/*
 * GRAPHITE, because `bench.css` `.ceremony` is graphite: "the instrument
 * filling the frame and speaking, not a black modal". The surface turning over
 * from paper to graphite is the moment the product stops being a design tool
 * and starts being a record, and it is the strongest single frame on this page.
 */
.stu-cer {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--stu-frame);
  color: var(--stu-readout);
  padding: 16px 15px 18px;
}

.stu-cer-eyebrow {
  margin: 0;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--stu-readout-lo);
}

.stu-cer-head {
  margin: 7px 0 0;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--stu-readout-hi);
}

.stu-cer-lede {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--stu-readout);
}

.stu-facts {
  margin: 14px 0 0;
  display: grid;
  gap: 1px;
  background: var(--stu-frame-line);
  border-top: 1px solid var(--stu-frame-line);
  border-bottom: 1px solid var(--stu-frame-line);
}

/* A recessed panel, not a second palette — the ceremony's own construction. */
.stu-fact {
  background: #322e3b;
  padding: 9px 11px 10px;
}

.stu-fact dt {
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--stu-readout-lo);
}

.stu-fact dd {
  margin: 3px 0 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--stu-readout-hi);
}

.stu-fact.flagged dd {
  color: #ff9ac8;
}

.stu-fact.cleared dd {
  color: var(--stu-beam-frame);
}

.stu-fact-sub {
  margin: 4px 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--stu-readout-lo);
}

.stu-decide {
  margin-top: 9px;
  border: 1px solid var(--stu-frame-line);
  border-radius: 7px;
  padding: 8px 9px 9px;
  background: #2b2833;
}

.stu-dq {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--stu-readout);
}

.stu-dq em {
  font-family: var(--stu-serif);
  font-style: italic;
  color: var(--stu-readout-hi);
}

/* The box the reason goes into. It is a real textarea in the product and a
   drawn one here; what matters is that it is empty until somebody writes. */
.stu-reasonbox {
  margin: 7px 0 0;
  min-height: 34px;
  border: 1px solid var(--stu-frame-line);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--stu-readout-hi);
  background: #241f2c;
}

.stu-placeholder {
  color: var(--stu-readout-lo);
}

.stu-reasonbox .stu-caret {
  background: var(--stu-beam-frame);
}

.stu-classes {
  display: grid;
  gap: 4px;
  margin-top: 7px;
}

/*
 * The three classes, and the fact that they are UNPRESSABLE until the box says
 * something. `reasonSatisfies` refuses a reason under eight characters, so a
 * depiction that drew them live from the start would be showing a gate that
 * does not gate.
 */
/*
 * NOT DIMMED BY ALPHA, for the same reason `.stu-rel.spent` is not: 0.45 on
 * #9C95AD composites to #5E596A and 2.14:1, and these are the three sentences a
 * compliance buyer has come to this page to read. The unavailable state is
 * carried by the colour holding at the readout's low tone while the armed state
 * lifts to the high one — 5.03:1 against 13:1, a difference nobody can miss and
 * a floor nobody falls through.
 */
.stu-class {
  display: block;
  border: 1px solid var(--stu-frame-line);
  border-radius: 6px;
  padding: 5px 8px;
  font-size: 11.5px;
  color: var(--stu-readout-lo);
  transition:
    color 0.3s ease-out,
    border-color 0.3s ease-out;
}

.stu-class.on {
  color: var(--stu-readout-hi);
  border-color: #5a5468;
}

.stu-class b {
  display: block;
  font-weight: 600;
}

.stu-class em {
  display: block;
  font-style: normal;
  font-size: 10.5px;
  color: var(--stu-readout-lo);
  margin-top: 1px;
}

.stu-cer-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-top: 13px;
}

.stu-cer-foot .stu-class {
  color: var(--stu-readout-hi);
  padding: 6px 11px;
}

.stu-confirm {
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  background: #3a3546;
  color: var(--stu-readout-lo);
  transition:
    background-color 0.4s ease-out,
    color 0.4s ease-out;
}

.stu-confirm.on {
  background: var(--stu-beam-frame);
  color: #0f1a19;
}

.stu-cer-note {
  margin: 9px 0 0;
  font-family: var(--stu-mono);
  font-size: 9px;
  letter-spacing: 0.05em;
  line-height: 1.5;
  color: var(--stu-readout-lo);
}

@media (prefers-reduced-motion: reduce) {
  .stu-said.reading i {
    animation: none !important;
  }

  .stu-mk,
  .stu-card,
  .stu-beat i {
    transition: none !important;
  }
}

}
/* The next site's own stylesheet.
   Tokens come from mock.css, which the app already loads — nothing new is
   invented here, and every colour that means something means the same thing it
   means in the product. Magenta appears on exactly one thing: a finding that
   stops a release, and the squiggle under the phrase it caught. */

.nx {
  --nx-paper: #faf8f4;
  --nx-surface: #fff;
  --nx-ink: #17151c;
  --nx-ink2: #4a4655;
  --nx-ink3: #6e6880;
  --nx-line: #e6e2da;
  --nx-flag: #d6006e;
  --nx-flag-wash: #fdebf4;
  --nx-judge: #6d5b8f;
  --nx-judge-wash: #f2eff7;
  --nx-cleared: #5b7a2e;
  --nx-beam: #0b756f;
  --nx-sans: 'Switzer', 'Avenir Next', system-ui, -apple-system, sans-serif;
  --nx-serif: 'Charter', 'Iowan Old Style', Palatino, Georgia, serif;
  /* Display only, and only out here. The public site carries no regulated
     text, so a display serif costs nothing it needs to keep. */
  --nx-display: 'Zodiak', 'Charter', Georgia, serif;
  --nx-mono: 'SF Mono', Menlo, ui-monospace, monospace;
  /* The sticky nav's height, so anything that has to sit under it can say so
     rather than guess. Measured, not estimated. */
  --nx-nav-h: 75px;
  /* The label column, shared by the table and by the cards above it, so a
     card sits exactly over the column it is about. */
  --nx-pt-label: 34%;
  --nx-pt-pad: 22px;
  --nx-pt-max: 980px;
  /*
    THREE TOKENS THAT WERE USED AND NEVER DECLARED.
    `--nx-bg`, `--nx-mut` and `--nx-sunk` appear in a block of rules ported
    from the wizard mock. A `var()` with no fallback and no declaration makes
    the whole property invalid, so `.nx-term.on { background: var(--nx-bg) }`
    set no background at all and the selected pill in every segmented control
    on this site was invisible. `--nx-mut` did the same to five text colours,
    which then inherited full-strength ink and stopped reading as secondary.
  */
  --nx-bg: #fff;
  --nx-mut: #6e6880;
  --nx-sunk: #efece5;
  background: var(--nx-paper);
  color: var(--nx-ink);
  font-family: var(--nx-sans);
  min-height: 100vh;
}

/* ---------------------------------------------------------------- chrome */
.nx-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 18px 44px;
  border-bottom: 1px solid var(--nx-line);
  background: var(--nx-surface);
  position: sticky;
  top: 0;
  z-index: 20;
}
.nx-nlrow {
  display: flex;
  align-items: center;
  gap: 26px;
}
/* The mark, where the name used to be set in the mono at 13/600 with .17em of
   tracking. 20px tall is the height the app masthead and the pre-auth chrome
   draw it at, and 54.4 = 313/115 x 20 is the file's own ratio at that height.
   `line-height:0` because an inline image brings the text baseline's descender
   space with it, which pushed the 26px gap to the first nav link out of true.

   The light file: `.nx-nav` is --nx-surface, #fff, and this palette is
   literals — the /next site does not invert. Black on white is 21:1. The
   FOOTER is the other ground and takes the knockout; see `.nx-fwm`. */
.nx-wm {
  display: inline-flex;
  align-items: center;
  line-height: 0;
  text-decoration: none;
  /* `.nx-nav` is a flex row that does not collapse at 390, so every item in it
     is shrinking. Text shrinks by wrapping; a picture shrinks by getting
     smaller, and the mark went to a 2px sliver before this line. */
  flex: none;
}
.nx-wm img {
  height: 20px;
  width: 54.4px;
  display: block;
  object-fit: contain;
}
.nx-nl {
  font-size: 13.5px;
  color: var(--nx-ink2);
  text-decoration: none;
}
.nx-nl:hover,
.nx-nl.on {
  color: var(--nx-ink);
}
.nx-sp {
  margin-left: auto;
}
.nx-ghost {
  font-size: 13.5px;
  color: var(--nx-ink2);
  text-decoration: none;
}
.nx-cta {
  font-size: 13.5px;
  font-weight: 500;
  background: var(--nx-ink);
  color: var(--nx-paper);
  padding: 9px 16px;
  border-radius: 7px;
  text-decoration: none;
}

/* ------------------------------------------------------------------ hero */
.nx-hero {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 56px;
  padding: 76px 44px 84px;
  align-items: center;
  max-width: 1400px;
  margin: 0 auto;
}
.nx-kick {
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  margin: 0 0 20px;
}
.nx-h1 {
  font-size: clamp(40px, 4.6vw, 60px);
  line-height: 1.01;
  letter-spacing: -0.04em;
  font-weight: 700;
  margin: 0 0 22px;
  text-wrap: balance;
}
.nx-lede {
  font-size: 18px;
  line-height: 1.52;
  color: var(--nx-ink2);
  margin: 0 0 32px;
  max-width: 46ch;
}
.nx-ctas {
  display: flex;
  gap: 11px;
  flex-wrap: wrap;
}
.nx-btn {
  font-size: 14.5px;
  font-weight: 500;
  padding: 12px 20px;
  border-radius: 7px;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  font-family: inherit;
}
.nx-btn.big {
  font-size: 16px;
  padding: 14px 26px;
}
.nx-btn.solid {
  background: var(--nx-ink);
  color: var(--nx-paper);
}
.nx-btn.ghost {
  background: var(--nx-surface);
  color: var(--nx-ink);
  border-color: #d3d0db;
}
/* Unavailable is a colour, never opacity — opacity fades the label and its
   ground at the same rate and lands around 2.6:1. */
.nx-btn:disabled {
  background: #f0eff3;
  border-color: var(--nx-line);
  color: var(--nx-ink3);
  cursor: not-allowed;
}
.nx-sub {
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--nx-ink3);
  margin: 14px 0 0;
}
/* The shipped animation sits in its own well and is not restyled. */
.nx-herodemo {
  min-width: 0;
}

/* ----------------------------------------------------------------- bands */
.nx-band {
  padding: 72px 44px;
  max-width: 1400px;
  margin: 0 auto;
}
.nx-band.alt {
  background: var(--nx-surface);
  max-width: none;
  border-top: 1px solid var(--nx-line);
  border-bottom: 1px solid var(--nx-line);
}
.nx-band.alt > * {
  max-width: 1400px;
  margin-inline: auto;
}
.nx-band.tight {
  padding: 56px 44px 76px;
}
.nx-h2 {
  font-size: clamp(26px, 2.7vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  font-weight: 700;
  margin: 0 0 34px;
  text-wrap: balance;
}
.nx-h2.spaced {
  margin-top: 64px;
}
.nx-ph1 {
  font-size: clamp(32px, 3.6vw, 44px);
  line-height: 1.06;
  letter-spacing: -0.035em;
  font-weight: 700;
  margin: 0 0 22px;
  max-width: 18ch;
}
.nx-lede2 {
  font-size: 17px;
  line-height: 1.55;
  color: var(--nx-ink2);
  margin: 0;
  max-width: 52ch;
}
.nx-lede2.wide {
  max-width: 62ch;
  margin-bottom: 32px;
}

.nx-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

/* the studios, sold */
.nx-tile {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 32px;
  border-radius: 14px;
  text-decoration: none;
  border: 1px solid var(--nx-line);
  background: var(--nx-surface);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.nx-tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 40px rgba(23, 21, 28, 0.1);
}
.nx-tile.copy {
  background: linear-gradient(168deg, #fff, #f6f4fb 88%);
}
.nx-tile.deck {
  background: linear-gradient(168deg, #fff, #f2f6f4 88%);
}
.nx-tn {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.024em;
  color: var(--nx-ink);
}
.nx-tl {
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--nx-ink2);
}
.nx-tk {
  font-family: var(--nx-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  margin-top: auto;
  padding-top: 8px;
}

.nx-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: center;
}
.nx-brow {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: 18px;
}
.nx-blab {
  font-size: 14.5px;
  color: var(--nx-ink2);
}
.nx-blab b {
  color: var(--nx-ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.nx-btrack {
  display: block;
  height: 11px;
  border-radius: 3px;
  background: #efedf2;
}
.nx-bbar {
  display: block;
  height: 11px;
  border-radius: 3px;
}
.nx-bbar.cl {
  background: var(--nx-cleared);
}
.nx-bbar.ju {
  background: var(--nx-judge);
}
.nx-bbar.st {
  background: var(--nx-flag);
}
.nx-bnote {
  font-family: var(--nx-mono);
  font-size: 10px;
  color: var(--nx-ink3);
  margin: 20px 0 0;
}

.nx-card {
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 12px;
  padding: 26px;
}
.nx-ct {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 0 0 18px;
}
.nx-rule {
  background: #faf9fc;
  border: 1px solid #efedf2;
  border-left: 3px solid var(--nx-flag);
  border-radius: 7px;
  padding: 15px;
}
.nx-q {
  font-family: var(--nx-serif);
  font-size: 15px;
  line-height: 1.45;
  margin: 11px 0 8px;
}
.nx-cite {
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.05em;
  color: var(--nx-ink3);
  margin: 0;
}
.nx-tag {
  font-family: var(--nx-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 3px;
  display: inline-block;
}
.nx-tag.stop {
  background: var(--nx-flag-wash);
  color: #a4004f;
}
.nx-tag.judge {
  background: var(--nx-judge-wash);
  color: #584a75;
}
.nx-inh {
  background: #faf9fc;
  border: 1px solid #efedf2;
  border-radius: 7px;
  padding: 16px;
}
.nx-inhrow {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 7px;
}
.nx-inhb {
  font-size: 13.5px;
  font-weight: 600;
}
.nx-inhv {
  font-family: var(--nx-mono);
  font-size: 11px;
  color: var(--nx-ink2);
  margin-left: auto;
}
.nx-lock {
  font-family: var(--nx-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: #e8f3f2;
  color: var(--nx-beam);
  padding: 3px 7px;
  border-radius: 3px;
}
.nx-inharrow {
  height: 22px;
  margin-left: 24px;
  border-left: 1.5px solid #d3d0db;
}

.nx-closer {
  padding: 84px 44px;
  text-align: center;
  background: var(--nx-surface);
  border-top: 1px solid var(--nx-line);
}
.nx-closer .nx-h2 {
  max-width: 22ch;
  margin: 0 auto 30px;
}

/* ------------------------------------------------------ the rails demo -- */
.nx-pick {
  display: flex;
  gap: 8px;
  margin: 0 0 22px;
  flex-wrap: wrap;
}
.nx-rp {
  font-size: 13px;
  color: var(--nx-ink2);
  background: var(--nx-surface);
  border: 1px solid #d3d0db;
  border-radius: 99px;
  padding: 8px 16px;
  cursor: pointer;
  font-family: inherit;
}
.nx-rp.on {
  background: var(--nx-ink);
  color: var(--nx-paper);
  border-color: var(--nx-ink);
  font-weight: 500;
}
.nx-rail {
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 12px;
  overflow: hidden;
}
.nx-railhead {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 15px 22px;
  border-bottom: 1px solid #efedf2;
  background: #faf9fc;
  position: relative;
}
.nx-rstep {
  font-family: var(--nx-mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.nx-rstep.done {
  color: var(--nx-beam);
}
.nx-rstep.on {
  color: var(--nx-ink);
  font-weight: 600;
}
.nx-rprog {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--nx-line);
}
.nx-rprog i {
  display: block;
  height: 2px;
  background: var(--nx-ink);
  transition: width 0.25s ease;
}
.nx-checkwrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  padding: 22px;
}
.nx-pane {
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 9px;
  padding: 20px;
  min-height: 240px;
}
.nx-pane.out {
  background: #faf9fc;
}
.nx-ph {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
}
.nx-mono {
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: var(--nx-ink3);
}
.nx-ctext {
  font-family: var(--nx-serif);
  font-size: 17px;
  line-height: 1.66;
  margin: 0;
}
/* THE SIGNATURE. Magenta only under a phrase a rule stopped. */
.nx-mk.stop {
  text-decoration: underline wavy var(--nx-flag);
  text-underline-offset: 5px;
}
.nx-mk.judge {
  text-decoration: underline wavy var(--nx-judge);
  text-underline-offset: 5px;
}
.nx-mk.ok {
  background: #f0f4e7;
  box-shadow: 0 0 0 3px #f0f4e7;
  font-weight: 600;
}
.nx-f {
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 7px;
  padding: 14px;
  margin-bottom: 11px;
}
.nx-fs {
  font-size: 13.5px;
  color: var(--nx-ink2);
  margin: 11px 0 0;
}
.nx-fs b {
  color: var(--nx-ink);
  background: #f0f4e7;
  box-shadow: 0 0 0 3px #f0f4e7;
}
.nx-sl {
  display: block;
  font-family: var(--nx-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nx-beam);
  margin-bottom: 6px;
}
.nx-wait,
.nx-clear {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--nx-ink2);
  margin: 0;
}
.nx-clear {
  color: var(--nx-cleared);
  font-weight: 600;
}
.nx-railfoot {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 15px 22px;
  border-top: 1px solid #efedf2;
  background: #faf9fc;
}
.nx-rnote {
  margin-left: auto;
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.11em;
  color: var(--nx-ink3);
}
.nx-keep {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 26px;
  padding: 20px 22px;
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 12px;
}
.nx-keep p {
  margin: 0;
  flex: 1;
  font-size: 14.5px;
  color: var(--nx-ink2);
}

/* -------------------------------------------------------------- /how --- */
.nx-steps {
  display: grid;
  gap: 28px;
  max-width: 74ch;
}
.nx-step {
  display: flex;
  gap: 22px;
}
.nx-sn {
  font-family: var(--nx-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--nx-ink3);
  padding-top: 5px;
}
.nx-st {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.017em;
  margin: 0 0 8px;
}
.nx-sb {
  font-size: 15px;
  line-height: 1.6;
  color: var(--nx-ink2);
  margin: 0;
}
.nx-nots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  max-width: 84ch;
}
.nx-not {
  font-family: var(--nx-serif);
  font-size: 17px;
  margin: 0;
  padding: 18px 22px;
  background: var(--nx-surface);
  border: 1px solid var(--nx-line);
  border-radius: 10px;
}

/* ------------------------------------------------------------ /trust --- */
.nx-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--nx-line);
  border: 1px solid var(--nx-line);
  border-radius: 12px;
  overflow: hidden;
}
.nx-fact {
  background: var(--nx-surface);
  padding: 24px 26px;
}
.nx-fk {
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  color: var(--nx-ink3);
  margin: 0 0 10px;
}
.nx-fv {
  font-size: 16px;
  line-height: 1.45;
  margin: 0;
}

/* ----------------------------------------------------------- footer ---- */
.nx-foot {
  background: var(--nx-ink);
  padding: 52px 44px 44px;
}
.nx-fcols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 160px)) 1fr;
  gap: 36px;
  max-width: 1400px;
  margin: 0 auto;
}
.nx-fcols a {
  display: block;
  font-size: 13px;
  color: rgba(240, 238, 244, 0.62);
  text-decoration: none;
  margin-bottom: 10px;
}
.nx-fcols a:hover {
  color: #fff;
}
.nx-fh {
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(240, 238, 244, 0.42);
  margin: 0 0 15px;
}
.nx-fend {
  text-align: right;
}
/* The footer's mark. `.nx-foot` is --nx-ink (#17151c), so this is the knockout
   — black on that ground is 1.15:1 and the knockout is 16.1:1. `margin-left:
   auto` rather than the `text-align:right` the <p> used to inherit from
   `.nx-fend`: an image is not text and does not answer to it. */
.nx-fwm {
  display: block;
  height: 20px;
  width: 54.4px;
  object-fit: contain;
  margin: 0 0 8px auto;
}
.nx-fsm {
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.05em;
  color: rgba(240, 238, 244, 0.42);
  line-height: 1.7;
  margin: 0;
}

/* -------------------------------------------------------------- phone -- */
@media (max-width: 900px) {
  .nx-hero,
  .nx-two,
  .nx-split,
  .nx-checkwrap,
  .nx-nots,
  .nx-facts {
    grid-template-columns: 1fr;
  }
  .nx-hero {
    padding: 44px 20px 56px;
    gap: 36px;
  }
  .nx-band,
  .nx-band.tight {
    padding: 48px 20px;
  }
  /*
    THE NAV SCROLLS, SO IT MUST NOT WRAP.
    `overflow-x: auto` says the row is a scroller; without a nowrap the flex
    items shrank to fit instead and the row never overflowed. Measured at
    390px: "How it works" set three words on three lines, "See it catch one"
    on four, and "Set up your brand" squeezed to a black sliver at the edge —
    a nav that reads as broken rather than as scrollable. The items keep their
    width now and the row scrolls, which is what the rule above always meant.
  */
  /* The nav loses 8px of padding here, so the token the sticky table head
     offsets by loses it too — otherwise rows show through an 8px band
     between the two between 861px and 900px. */
  .nx { --nx-nav-h: 67px; }
  .nx-nav {
    padding: 14px 20px;
    gap: 16px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nx-nav::-webkit-scrollbar { display: none; }
  .nx-nav > *,
  .nx-nlrow > * { flex: 0 0 auto; white-space: nowrap; }
  .nx-nav > .nx-sp { flex: 0 1 auto; min-width: 0; }

  .nx-foot {
    padding: 40px 20px;
  }
  .nx-fcols {
    grid-template-columns: 1fr 1fr;
  }
  .nx-fend {
    text-align: left;
    grid-column: 1 / -1;
  }
  /* The column goes left here, and `text-align` cannot move a picture — the
     mark was still pinned right with the tagline under it on the left. */
  .nx-fwm {
    margin-left: 0;
  }
  .nx-keep {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* what you bring, what you get */
.nx-three{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.nx-in{padding:28px;border-radius:12px;border:1px solid var(--nx-line);background:var(--nx-surface)}
.nx-in.hot{background:linear-gradient(168deg,#fff,#f2f6f4 90%);border-color:#cfe3dd}
.nx-ik{font-family:var(--nx-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--nx-ink3);margin:0 0 12px}
.nx-it{font-size:20px;font-weight:700;letter-spacing:-.022em;margin:0 0 10px}
.nx-ib{font-size:14.5px;line-height:1.55;color:var(--nx-ink2);margin:0}

/* who it is for */
.nx-who{display:grid;grid-template-columns:repeat(5,1fr);gap:18px}
.nx-wt{font-size:15.5px;font-weight:600;margin:0 0 7px;letter-spacing:-.012em}
.nx-wb{font-size:13.5px;line-height:1.5;color:var(--nx-ink2);margin:0}
@media (max-width:900px){
  .nx-three{grid-template-columns:1fr}
  .nx-who{grid-template-columns:1fr 1fr}
}

/* the rest of the platform */
.nx-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--nx-line);
  border:1px solid var(--nx-line);border-radius:12px;overflow:hidden}
.nx-lk{display:flex;flex-direction:column;gap:5px;padding:20px 22px;background:var(--nx-surface);
  text-decoration:none}
.nx-lk:hover{background:#faf9fc}
.nx-lk b{font-size:15px;font-weight:600;color:var(--nx-ink);letter-spacing:-.012em}
.nx-lk span{font-size:13px;line-height:1.45;color:var(--nx-ink2)}
@media (max-width:900px){.nx-grid{grid-template-columns:1fr 1fr}}

/* the moment: wrong words in, right words out */
.nx-magic{display:grid;gap:0;border:1px solid var(--nx-line);border-radius:14px;
  overflow:hidden;background:var(--nx-surface)}
.nx-mrow{display:flex;gap:22px;align-items:baseline;padding:28px 30px}
.nx-mrow.now{background:linear-gradient(168deg,#f7fbf3,#fff 90%)}
.nx-ml{font-family:var(--nx-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--nx-ink3);flex:none;width:72px;padding-top:6px}
.nx-mtext{font-family:var(--nx-serif);font-size:clamp(19px,2vw,24px);line-height:1.5;margin:0;
  color:var(--nx-ink)}
.nx-was{text-decoration:underline wavy var(--nx-flag);text-underline-offset:6px;
  text-decoration-thickness:1.8px}
.nx-now{background:#eef5e4;box-shadow:0 0 0 4px #eef5e4;border-radius:1px;font-weight:600}
.nx-marrow{height:1px;background:var(--nx-line)}
.nx-mfoot{font-size:15px;color:var(--nx-ink2);margin:22px 0 0}

/* ---- RHYTHM ----
   Every band was the same: 72px of padding, a heading, a grid. Nothing told
   the eye which section mattered. The moment the product actually sells goes
   full-bleed and dark; the audience list drops to a thin strip. */
.nx-band.dark{background:var(--nx-ink);color:#f4f2f8;max-width:none;padding:96px 44px 88px}
.nx-band.dark > *{max-width:1240px;margin-inline:auto}
.nx-band.dark .nx-h2{color:#fff;max-width:20ch}
.nx-h2.big{font-size:clamp(32px,4vw,50px);letter-spacing:-.038em;line-height:1.02}
.nx-band.dark .nx-magic{background:#211f29;border-color:#3a3646}
.nx-band.dark .nx-mrow.now{background:linear-gradient(168deg,#1c2a1f,#211f29 90%)}
.nx-band.dark .nx-ml{color:#a49eb6}
.nx-band.dark .nx-mtext{color:#f4f2f8}
.nx-band.dark .nx-now{background:#2c4022;box-shadow:0 0 0 4px #2c4022;color:#dff0c8}
.nx-band.dark .nx-marrow{background:#3a3646}
.nx-band.dark .nx-mfoot{color:#cfcbda}

.nx-strip{padding:34px 44px;border-top:1px solid var(--nx-line);
  border-bottom:1px solid var(--nx-line);background:var(--nx-surface)}
.nx-strip .nx-who{max-width:1400px;margin:0 auto}
.nx-stripk{font-family:var(--nx-mono);font-size:9.5px;letter-spacing:.15em;text-transform:uppercase;
  color:var(--nx-ink3);margin:0 auto 18px;max-width:1400px}
.nx-strip .nx-wt{font-size:14px}
.nx-strip .nx-wb{font-size:12.5px}

/* the studio captures sit above the words, full bleed to the card edge */
.nx-tile{padding:0;overflow:hidden}
.nx-tshot{display:block;width:100%;border-bottom:1px solid var(--nx-line)}
.nx-tile .nx-tn{padding:24px 28px 0}
.nx-tile .nx-tl{padding:0 28px}
.nx-tile .nx-tk{padding:0 28px 24px}
.nx-diagram{max-width:900px}

/* ---- the anonymous set-up ---- */
.nx-startband{max-width:1100px}
.nx-stepcount{font-family:var(--nx-mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--nx-ink3);margin-right:20px}
.nx-field{display:block;max-width:520px;margin:0 0 26px}
.nx-field span{display:block;font-family:var(--nx-mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--nx-ink3);margin-bottom:9px}
.nx-input{width:100%;font-family:inherit;font-size:17px;color:var(--nx-ink);
  background:var(--nx-surface);border:1px solid #d3d0db;border-radius:8px;padding:13px 15px}
.nx-input:focus{outline:2px solid var(--nx-ink);outline-offset:1px}
.nx-flabel{font-family:var(--nx-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--nx-ink3);margin:0 0 11px}
.nx-startfoot{display:flex;align-items:center;gap:12px;margin-top:32px;flex-wrap:wrap}
.nx-warn{font-size:13.5px;color:var(--nx-ink2)}
.nx-rulelist{display:grid;gap:1px;background:var(--nx-line);border:1px solid var(--nx-line);
  border-radius:12px;overflow:hidden}
.nx-rulerow{display:flex;align-items:flex-start;gap:16px;padding:15px 18px;background:var(--nx-surface)}
.nx-rulerow.off{background:#f6f5f3}
.nx-rulerow.off .nx-rq{color:var(--nx-ink3);text-decoration:line-through}
.nx-rq{font-family:var(--nx-serif);font-size:15.5px;line-height:1.4;margin:0;flex:1}
.nx-drop{font-size:12.5px;color:var(--nx-ink2);background:none;border:1px solid #d3d0db;
  border-radius:6px;padding:6px 11px;cursor:pointer;font-family:inherit;white-space:nowrap}
.nx-drop:hover{color:var(--nx-ink);border-color:var(--nx-ink)}
.nx-textarea{width:100%;font-family:var(--nx-serif);font-size:17px;line-height:1.6;
  color:var(--nx-ink);background:none;border:0;resize:vertical;outline:none}
.nx-caught{font-family:var(--nx-serif);font-size:14px;color:var(--nx-ink2);margin:8px 0 0;
  padding-left:11px;border-left:2px solid var(--nx-flag)}
.nx-usethis{margin-left:11px;font-size:12px;font-weight:500;background:var(--nx-ink);
  color:var(--nx-paper);border:0;border-radius:5px;padding:5px 10px;cursor:pointer;
  font-family:inherit}

/* ---- pricing ---- */
.nx-plans{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin:12px 0 34px}
.nx-plan{display:flex;flex-direction:column;background:var(--nx-surface);
  border:1px solid var(--nx-line);border-radius:14px;padding:28px}
.nx-plan.lead{border-color:var(--nx-ink);box-shadow:0 14px 40px rgba(23,21,28,.08)}
.nx-pn{font-family:var(--nx-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--nx-ink3);margin:0 0 16px}
.nx-pp{margin:0}
.nx-pp b{font-size:46px;font-weight:700;letter-spacing:-.04em;color:var(--nx-ink)}
.nx-pu{font-size:13px;color:var(--nx-ink3);margin:4px 0 16px}
.nx-pw{font-size:14.5px;line-height:1.5;color:var(--nx-ink2);margin:0 0 20px}
.nx-plist{list-style:none;margin:0 0 24px;padding:0;display:grid;gap:9px}
.nx-plist li{font-size:14px;line-height:1.45;color:var(--nx-ink2);padding-left:20px;position:relative}
.nx-plist li::before{content:"";position:absolute;left:2px;top:7px;width:8px;height:8px;
  border-radius:2px;background:var(--nx-cleared)}
.nx-plist li.no{color:var(--nx-ink3)}
.nx-plist li.no::before{background:none;border:1px solid #d3d0db}
.nx-plan .nx-btn{margin-top:auto;text-align:center}
.nx-faq + .nx-pnotes { margin-top: 26px; }
.nx-pnotes{display:grid;gap:12px;max-width:70ch}
.nx-pnotes p{font-size:14px;line-height:1.55;color:var(--nx-ink2);margin:0}
.nx-pnotes b{color:var(--nx-ink)}
.nx-pnotes a{color:var(--nx-beam)}

/* The billing-term switch. Two buttons, not a toggle: a toggle needs a label
   saying which way is on, and two buttons say it themselves. */
/*
  THE SELECTED STATE, WHICH DID NOT EXIST.

  Measured on the live page: selected and unselected were identical at 1.00:1
  on both fill and text. Two of the three tokens these rules named were never
  declared, so `color: var(--nx-mut)` was invalid and inherited full ink, and
  `background: var(--nx-bg)` was invalid and stayed transparent. The only
  surviving signal was a 2px shadow at 8% black — 1.19:1 against the track, in
  a sliver under one edge.

  Declaring the tokens is not the fix. White on the #efece5 track is 1.18:1,
  so the design was already under the 3:1 floor for a non-text control before
  the variables went missing. The pill takes ink: 15.3:1 against the track,
  and the two labels land about fifty steps of lightness apart.

  This is a pricing page, so the cost of an unreadable state is exact — a
  visitor cannot tell which currency the number in front of them is in.
*/
.nx-terms{display:inline-flex;gap:2px;margin:30px 0 6px;padding:3px;border-radius:999px;background:var(--nx-paper);border:1px solid var(--nx-line)}
.nx-term{display:inline-flex;align-items:center;min-height:38px;padding:8px 18px;border:0;border-radius:999px;background:transparent;color:var(--nx-ink3);font:inherit;font-size:14px;font-weight:500;cursor:pointer}
.nx-term:hover{color:var(--nx-ink)}
.nx-term.on{background:var(--nx-ink);color:var(--nx-paper)}
.nx-term:focus-visible{outline:2px solid var(--nx-beam);outline-offset:2px}

/* The wizard's quieter ways in. Deliberately not buttons: the website field is
   the main road, and two more solid buttons beside it would make three equal
   choices out of one choice and two escapes. */
.nx-alts{margin-top:22px;display:flex;flex-wrap:wrap;gap:16px;align-items:baseline}
.nx-linkish{border:0;background:none;padding:0;font:inherit;font-size:15px;color:var(--nx-beam);cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.nx-linkish:focus-visible{outline:2px solid var(--nx-beam);outline-offset:3px;border-radius:2px}
.nx-fine{flex-basis:100%;margin:2px 0 0;font-size:13px;line-height:1.5;color:var(--nx-mut)}
.nx-pastewrap{margin-top:18px;display:flex;flex-direction:column;gap:12px;align-items:flex-start}
/* The locked tease. Muted rather than hidden — it is a real finding held back,
   and dressing it as an error would read as something having gone wrong. */
.nx-rulerow.locked{opacity:.72}
.nx-tag.mut{background:var(--nx-sunk,rgba(0,0,0,.06));color:var(--nx-mut)}

/* The statement and its evidence, stacked in one column. `min-width:0` is what
   lets a long quote wrap instead of forcing the flex row wider than the card. */
.nx-rulebody{flex:1;min-width:0}
/* The line on their own page a suggested rule was drawn from. Quiet and
   indented: it is evidence under a claim, not a second claim. */
.nx-fromsite{margin:6px 0 0;padding-left:12px;border-left:2px solid var(--nx-line,rgba(0,0,0,.12));font-size:14px;line-height:1.5;color:var(--nx-mut);font-style:italic}
/* The tag sits on the statement's first line rather than floating at the top
   of a two-line block. */
.nx-rulerow .nx-tag{margin-top:2px;flex:none}

/* ---------------------------------------------------------------------------
   The wizard on a phone.

   `.nx-checkwrap`, `.nx-plans` and `.nx-startfoot` already stack or wrap at
   this width. These four are the ones added with the wizard and they are the
   ones that needed it: a rule row is a fixed-width tag beside a body, and at
   390px that leaves the statement four words to a line with its quote under
   it. The tag goes above instead, which is also the order it reads in.
   --------------------------------------------------------------------------- */
/*
  THE SECTIONS TAKE A ROW OF THEIR OWN, AND THE WAY IN STAYS ON SCREEN.

  Signing in and the CTA are what a phone visitor came for, and both were past
  the right edge of a scroll with no cue that it scrolled. Below this width the
  nav wraps: the identity and the two actions hold the first row, and the
  sections scroll along the second. Above it the whole row still fits on one
  line — measured at 700px, the CTA ends 20px inside the edge — so the second
  row would be a row of nothing.
*/
@media (max-width: 640px) {
  .nx-nav { flex-wrap: wrap; row-gap: 10px; overflow-x: visible; }
  .nx-nlrow {
    order: 2;
    flex: 1 0 100%;
    overflow-x: auto;
    gap: 18px;
    scrollbar-width: none;
  }
  .nx-nlrow::-webkit-scrollbar { display: none; }
}

@media (max-width:640px){
  .nx-rulerow{flex-direction:column;align-items:flex-start;gap:8px}
  .nx-rulerow .nx-tag{margin-top:0}
  .nx-rulebody{width:100%}
  /* The term switch and the two quiet ways in, full width rather than
     squeezed onto one line with a tap target each side of 40px. */
  .nx-terms{width:100%;justify-content:stretch}
  /* 35px was the measured height. A finger needs 44. */
  .nx-term{flex:1;justify-content:center;text-align:center;min-height:44px}
  .nx-alts{gap:12px}
  .nx-alts .nx-linkish{flex-basis:100%}
}

/* ==========================================================================
   THE PRICE CARDS

   Two cards, and the recommended one is visibly the recommended one. Weight
   comes from a heavier border and a lift, not from a fill or a gradient: the
   band behind them is already paper, and a coloured card on this site would be
   the loudest thing on any page.
   ========================================================================== */

.nx-pmeta {
  margin: 14px 0 0;
  font-family: var(--nx-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--nx-ink3);
}
.nx-pmeta i { font-style: normal; opacity: 0.45; padding: 0 6px; }

/*
  THE CARD IS THE HEAD OF ITS COLUMN.

  The grid opens with an empty cell exactly the width of the table's label
  column, so Solo sits over the Solo column and Studio over Studio, and the
  card and the seven rows under it read as one object. The table below has no
  head row of its own for the same reason: two plan names forty pixels apart
  were one fact printed twice.

  An earlier version put a third card here for Enterprise. It aligned nothing,
  and it put the option with no price on it first on a pricing page. It closes
  the page now.
*/
.nx-cards {
  display: grid;
  grid-template-columns: var(--nx-pt-label) 1fr 1fr;
  max-width: var(--nx-pt-max);
  margin: 26px 0 0;
}
/*
  THE TWO CARDS BUTT TOGETHER, and that is what makes the alignment exact.

  A grid gap between them would shift both off the table's column edges by
  half the gap, and there is no way to give a `td` a matching margin. Sharing
  an edge also says the right thing: this is one object with two columns, the
  same object the seven rows underneath are.
*/
.nx-cards .nx-card + .nx-card { margin-left: -1px; }
.nx-card {
  padding: 20px var(--nx-pt-pad) 22px;
  border: 1px solid var(--nx-line);
  border-radius: 12px 12px 0 0;
  border-bottom: 0;
  background: var(--nx-surface);
  display: flex;
  flex-direction: column;
}
/* The recommended plan, weighted rather than coloured: a heavier frame and a
   fill one step off the band. The band is paper, so a white column reads as
   lifted without anything being tinted. */
.nx-card.pick {
  border-color: var(--nx-ink);
  border-width: 1.5px;
}
.nx-card.pick .nx-cardname { color: var(--nx-ink); }

.nx-cardname {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-family: var(--nx-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  min-height: 22px;
}
.nx-cardbadge {
  font-size: 9.5px;
  letter-spacing: 0.12em;
  padding: 3px 8px;
  border-radius: 999px;
  color: var(--nx-beam);
  background: color-mix(in srgb, var(--nx-beam) 10%, var(--nx-surface));
}
.nx-cardpitch {
  margin: 10px 0 0;
  font-family: var(--nx-serif);
  font-size: 15px;
  line-height: 1.4;
  color: var(--nx-ink2);
  min-height: 2.8em;
}
.nx-cardprice {
  margin: 16px 0 0;
  font-size: 38px;
  line-height: 1;
  letter-spacing: -0.03em;
  font-weight: 700;
  color: var(--nx-ink);
  font-variant-numeric: tabular-nums;
}
.nx-cardper { font-size: 14px; font-weight: 400; letter-spacing: 0; color: var(--nx-ink3); }
.nx-cardbilled {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--nx-ink3);
  min-height: 2.9em;
}
.nx-cardcta { margin-top: 16px; align-self: stretch; text-align: center; }
.nx-cardtrial {
  margin: 10px 0 0;
  font-size: 12.5px;
  color: var(--nx-ink3);
}

/* The yearly saving, on the control where the decision is made. */
.nx-term.on .nx-termtag {
  color: var(--nx-paper);
  background: rgba(255, 255, 255, 0.16);
}
.nx-termtag {
  margin-left: 7px;
  font-family: var(--nx-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 999px;
  color: var(--nx-beam);
  background: color-mix(in srgb, var(--nx-beam) 11%, var(--nx-surface));
}

/* ==========================================================================
   THE DIFFERENCE TABLE

   Seven rows, and a reader travels down a column. Every cell is a number, a
   dash, or two to four words, with an optional five-word note under it — the
   contract is enforced in `planTable.ts` and the type there has no room for a
   sentence.
   ========================================================================== */

/* No box. The cards above are the objects on this band; a second bordered
   panel under them made three boxes on one screen, and the rules inside the
   table already do the work a border would. */
.nx-ptwrap { max-width: var(--nx-pt-max); }
/* The rule the cards stand on, drawn once across the whole width so the two
   columns and the label column share one baseline. */
.nx-pt { border-top: 1px solid var(--nx-ink); }
/*
  The two columns carry the cards' fill down the table, so the object that
  starts at the card ends at the last row.

  The recommended column had ink down both edges to continue its card's frame.
  It read as a box somebody forgot to close: the group headings span all three
  columns, so the frame breaks at every heading and cannot be shut at the
  bottom. The cards carry the recommendation, the alignment carries the tie,
  and the table keeps hairlines.
*/
.nx-pt tbody tr:not(.nx-pt-group) td { background: var(--nx-surface); }
.nx-pt tbody tr:not(.nx-pt-group) td + td { border-left: 1px solid var(--nx-line); }

/*
  SEPARATE BORDERS, AND THAT IS WHAT MAKES THE STICKY HEAD OPAQUE.
  Under `border-collapse: collapse` the table paints the cell backgrounds, and
  a cell lifted out of that flow by `position: sticky` loses its background
  with them. The rows then scroll visibly through the head.
*/
.nx-pt {
  width: 100%;
  /* FIXED, so the declared column widths are the ones drawn. Under `auto` the
     browser sizes columns from their content and the value columns came out
     288px and 359px against two 323px cards — the alignment the empty corner
     cell buys, given away one row lower. */
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  text-align: left;
}

/* The head is names only now. The price moved to the cards, so there is
   nothing here worth 160px of a viewport and nothing worth sticking. */
/* Present, sized, and drawn as nothing. Its only jobs are to name the columns
   for a screen reader and to declare the widths `table-layout: fixed` reads. */
.nx-pt-head th,
.nx-pt-head td { padding: 0; border: 0; height: 0; line-height: 0; }
.nx-pt-plan { width: 33%; }

.nx-pt-group th {
  padding: 20px 0 6px;
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  font-weight: 500;
  border-bottom: 1px solid var(--nx-line);
}

.nx-pt tbody tr:not(.nx-pt-group) th,
.nx-pt tbody tr:not(.nx-pt-group) td {
  padding: 10px var(--nx-pt-pad);
  border-bottom: 1px solid var(--nx-line);
  vertical-align: top;
}
/* The label column carries the band's own left edge, so the first cell has no
   padding and the two value columns align with the cards. */
.nx-pt tbody tr:not(.nx-pt-group) th:first-child,
.nx-pt thead td:first-child { padding-left: 0; }
.nx-pt tbody tr:last-child th,
.nx-pt tbody tr:last-child td { border-bottom: 0; }

.nx-pt-what {
  width: var(--nx-pt-label);
  font-size: 14px;
  font-weight: 500;
  color: var(--nx-ink);
}
.nx-pt-val {
  font-weight: 600;
  font-size: 15px;
  color: var(--nx-ink);
}
.nx-pt-note {
  display: block;
  margin-top: 0;
  font-style: normal;
  font-size: 12.5px;
  color: var(--nx-ink3);
}

/* The one row that is the same on both, said quietly. It earns its line by
   stopping a reader counting reviewers as seats. */
.nx-pt-same .nx-pt-val { font-weight: 500; color: var(--nx-ink2); }

/* ==========================================================================
   WHAT BOTH PLANS DO

   The thirteen parity rows that used to be in the table. Read once.
   ========================================================================== */

.nx-shared { margin: 30px 0 0; max-width: var(--nx-pt-max); }

/* --- what the money buys ------------------------------------------------- */

.nx-lede3 {
  margin: 14px 0 0;
  max-width: 62ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--nx-ink2);
}

.nx-sell {
  max-width: var(--nx-pt-max);
  margin: 30px 0 8px;
}
.nx-sellh {
  margin: 0;
  font-size: 24px;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--nx-ink);
}
.nx-sellsub {
  margin: 8px 0 0;
  max-width: 56ch;
  font-family: var(--nx-serif);
  font-size: 15.5px;
  line-height: 1.5;
  color: var(--nx-ink2);
}
.nx-sellgrid {
  margin: 26px 0 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px;
  background: var(--nx-line);
  border: 1px solid var(--nx-line);
  border-radius: 12px;
  overflow: hidden;
}
/* Five beats in a two-column grid leaves one cell over. The last one takes
   both, which reads as the closing point rather than as a gap. */
.nx-beat:last-child { grid-column: 1 / -1; }
.nx-beat {
  background: var(--nx-surface);
  padding: 20px 22px 18px;
}
.nx-beat h3 {
  margin: 0;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--nx-ink);
}
.nx-beat p {
  margin: 7px 0 0;
  font-family: var(--nx-serif);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--nx-ink2);
}
.nx-beat a {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nx-beam);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.nx-beat a::after { content: ' \2192'; }
.nx-beat a:hover { border-bottom-color: var(--nx-beam); }

.nx-sellcta {
  margin: 22px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}
.nx-selllink {
  font-size: 14.5px;
  color: var(--nx-ink2);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--nx-line);
}
.nx-selllink:hover { color: var(--nx-ink); text-decoration-color: currentColor; }

.nx-sharedcta {
  margin: 18px 0 0;
  font-size: 14.5px;
  color: var(--nx-ink3);
}
.nx-sharedcta a { color: var(--nx-beam); text-underline-offset: 3px; }

/* --- the close ----------------------------------------------------------- */
.nx-close {
  max-width: var(--nx-pt-max);
  margin: 44px 0 0;
  padding: 28px 26px 26px;
  border: 1px solid var(--nx-ink);
  border-radius: 12px;
  background: var(--nx-surface);
}
.nx-close h2 {
  margin: 0;
  font-size: 23px;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--nx-ink);
}
.nx-close p {
  margin: 10px 0 0;
  max-width: 64ch;
  font-family: var(--nx-serif);
  font-size: 15px;
  line-height: 1.55;
  color: var(--nx-ink2);
}
.nx-closecta {
  margin: 20px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}

/* The row labels that carry an explainer. Underlined on the label itself, so
   the affordance is on the words a reader is already looking at. */
.nx-pt-what a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--nx-line);
}
.nx-pt-what a:hover { text-decoration-color: var(--nx-beam); color: var(--nx-beam); }

.nx-ask p a { color: var(--nx-beam); text-underline-offset: 3px; white-space: nowrap; }

/* --- the four facts a regulated buyer has to clear internally ------------- */
.nx-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin: 34px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid var(--nx-line);
  max-width: var(--nx-pt-max);
}
.nx-trust a {
  font-family: var(--nx-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--nx-ink3);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.nx-trust a:hover { color: var(--nx-ink); border-bottom-color: var(--nx-ink); }

/* --- what stops a purchase ----------------------------------------------- */
.nx-faq { margin: 44px 0 0; max-width: var(--nx-pt-max); }
.nx-faqh {
  margin: 0 0 18px;
  font-size: 22px;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--nx-ink);
}
.nx-ask { border-top: 1px solid var(--nx-line); }
.nx-ask:last-of-type { border-bottom: 1px solid var(--nx-line); }
.nx-ask summary {
  list-style: none;
  cursor: pointer;
  padding: 13px 34px 13px 0;
  position: relative;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--nx-ink);
}
.nx-ask summary::-webkit-details-marker { display: none; }
/* A plus that becomes a minus. Two rules rather than a glyph, so it is the
   same weight as the hairlines around it. */
.nx-ask summary::before,
.nx-ask summary::after {
  content: '';
  position: absolute;
  right: 4px;
  top: 50%;
  background: var(--nx-ink3);
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.nx-ask summary::before { width: 11px; height: 1px; margin-top: -0.5px; }
.nx-ask summary::after { width: 1px; height: 11px; right: 9px; margin-top: -5.5px; }
.nx-ask[open] summary::after { transform: rotate(90deg); opacity: 0; }
.nx-ask summary:hover { color: var(--nx-ink); }
.nx-ask summary:focus-visible { outline: 2px solid var(--nx-beam); outline-offset: 2px; }
.nx-ask p {
  margin: 0;
  padding: 0 60px 16px 0;
  font-family: var(--nx-serif);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--nx-ink2);
}

/* --- the line that is not a plan ----------------------------------------- */
.nx-talk {
  max-width: var(--nx-pt-max);
  margin: 40px 0 0;
  padding: 20px 22px;
  border: 1px dashed var(--nx-line);
  border-radius: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 22px;
}
/* The plan a buyer chose, carried into the wizard's chrome. Quiet: it is a
   receipt for a decision already made, not a second offer. */
.nx-chose {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 11px;
  border: 1px solid var(--nx-line);
  border-radius: 999px;
  background: var(--nx-surface);
  white-space: nowrap;
}
.nx-chose b {
  font-family: var(--nx-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nx-ink);
}
.nx-chose i { font-style: normal; font-size: 12px; color: var(--nx-ink3); }
@media (max-width: 640px) { .nx-chose i { display: none; } }

.nx-talkh { margin: 0; font-size: 15px; font-weight: 600; color: var(--nx-ink); }
.nx-talkb {
  margin: 0;
  flex: 1 1 22em;
  font-family: var(--nx-serif);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--nx-ink2);
}
.nx-sharedh {
  margin: 0 0 12px;
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--nx-ink3);
}
.nx-shared ul {
  margin: 0;
  padding: 0;
  list-style: none;
  columns: 2;
  column-gap: 44px;
}
.nx-shared li {
  break-inside: avoid;
  padding: 5px 0 5px 20px;
  position: relative;
  font-family: var(--nx-serif);
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--nx-ink2);
}
.nx-shared li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 12px;
  width: 9px;
  height: 5px;
  border-left: 1.5px solid var(--nx-beam);
  border-bottom: 1.5px solid var(--nx-beam);
  transform: rotate(-45deg);
}

/* --- narrow: the columns go, and nothing is left unattributed ------------- */

/*
  A COMPARISON TABLE THAT SCROLLS SIDEWAYS ON A PHONE IS NOT ONE. Below 860px
  the table stops being a grid. Each row becomes its label and then one block
  per plan, and every block names its own plan from `data-plan`.
*/
@media (max-width: 860px) {
  /* Stacked, and each card closes itself again — it no longer stands on a
     column, so a card with no bottom edge would read as unfinished. */
  .nx-cards { grid-template-columns: 1fr; gap: 14px; margin-bottom: 26px; }
  .nx-cards-corner { display: none; }
  .nx-cards .nx-card + .nx-card { margin-left: 0; }
  .nx-cards .nx-card { border-radius: 12px; }
  .nx-pt { table-layout: auto; }
  .nx-card { border-bottom: 1px solid var(--nx-line); }
  .nx-card.pick { border-bottom-color: var(--nx-ink); }
  .nx-pt tbody tr:not(.nx-pt-group) td { background: none; }
  .nx-pt tbody tr:not(.nx-pt-group) td + td { border-left: 0; }
  .nx-ask p { padding-right: 0; }
  .nx-sellgrid { grid-template-columns: 1fr; }
  .nx-beat:last-child { grid-column: auto; }
  .nx-sellcta, .nx-closecta { flex-direction: column; align-items: stretch; }
  .nx-sellcta .nx-btn, .nx-closecta .nx-btn { text-align: center; }
  .nx-selllink { text-align: center; }
  .nx-cardpitch, .nx-cardbilled { min-height: 0; }
  .nx-shared ul { columns: 1; }

  .nx-pt,
  .nx-pt thead,
  .nx-pt tbody,
  .nx-pt tr,
  .nx-pt th,
  .nx-pt td {
    display: block;
    width: auto;
  }
  .nx-pt thead { display: none; }

  .nx-pt-group th { padding: 20px 16px 4px; }
  .nx-pt tbody tr:not(.nx-pt-group) {
    border-bottom: 1px solid var(--nx-line);
    padding: 10px 0 12px;
  }
  .nx-pt tbody tr:not(.nx-pt-group) th,
  .nx-pt tbody tr:not(.nx-pt-group) td {
    border-bottom: 0;
    padding: 2px 16px;
  }
  .nx-pt tbody tr:not(.nx-pt-group) th { padding-bottom: 6px; }
  .nx-pt tbody td { display: flex; align-items: baseline; gap: 8px; }
  .nx-pt tbody td::before {
    content: attr(data-plan);
    flex: 0 0 5.5em;
    font-family: var(--nx-mono);
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--nx-ink3);
  }
  .nx-pt-note { display: inline; margin-left: 6px; }
}

/* Reachable by a screen reader, absent from the page. */
.nx-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* ==========================================================================
   PRICING — THE VISUAL PASS

   Loaded after `next.css` and deliberately kept apart from it, because these
   rules were measured rather than chosen. Fourteen live pricing pages were
   read at 1440 for computed styles and raw rule text, and three specs written
   before that sweep did not survive it:

     NO `translateY` ON A CTA. Not one of the fourteen lifts its button on
     hover. The premium hover is a background step of 8-35/255 with a shadow
     that opens, and the lift is the tell of a template.

     NO SHRUNKEN CURRENCY SYMBOL. Zero `<sup>`, zero `vertical-align`, zero
     size reduction across fourteen sites. The `€` is set at the same size and
     weight as the digits.

     NO `tabular-nums` ON A DISPLAY PRICE. Tabular figures give Avenir Next's
     `1` wide sidebearings, so €119 and €149 read gappy at 52px. Proportional
     lining figures here; tabular stays in the table, where columns align.

   The shadow on the solid button is a five-layer penumbra whose alpha RISES
   as its offset FALLS, which is what a contact shadow does. One blurred blob
   is what a fake one does.

   THE LIT CHANNEL is painted once on `.nx-ptwrap::before`, behind the table,
   rather than as borders on the recommended column's cells. The group
   headings span all three columns, so a per-cell frame breaks at every
   heading and cannot be closed at the bottom — which is exactly what made the
   earlier attempt read as an unfinished box.
   ========================================================================== */

/* ==========================================================================
   PRICING — VISUAL PASS
   Replaces the corresponding rules in next.css. Keyed to existing classes.
   ========================================================================== */

/* --- 0. tokens and the band ---------------------------------------------- */

.nx {
  --nx-pt-max: 1040px;
  --nx-pt-pad: 24px;
  --nx-ink-lift: #23202b;   /* the ink object's top-lit face */
  --nx-ink-press: #100e14;  /* the ink object, pressed */
  --nx-edge: #8b8695;       /* 3.3:1 on white — a control boundary, not a hairline */
  --nx-cap: #f3f0ea;        /* the unpromoted card's head band */
  --nx-hair2: #d6d1c6;      /* one step darker than --nx-line, for section rules */
}

.nx-priceband *,
.nx-priceband *::before,
.nx-priceband *::after { box-sizing: border-box; }

.nx-priceband {
  max-width: calc(var(--nx-pt-max) + 88px);
}

.nx-switches {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* --- 1. the corner cell, which was 350px of nothing ----------------------- */

.nx-cards-corner {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 7px;
  padding: 0 26px 24px 0;
}
.nx-cards-corner span {
  font-family: var(--nx-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.3;
  color: var(--nx-ink3);
  padding-left: 15px;
  position: relative;
}
.nx-cards-corner span::before {
  content: '';
  position: absolute;
  left: 0;
  top: 5px;
  width: 7px;
  height: 4px;
  border-left: 1.5px solid var(--nx-beam);
  border-bottom: 1.5px solid var(--nx-beam);
  transform: rotate(-45deg);
}

.nx-pmeta { display: none; }

/* --- 2. the cards -------------------------------------------------------- */

.nx-cards {
  display: grid;
  grid-template-columns: var(--nx-pt-label) 1fr 1fr;
  max-width: var(--nx-pt-max);
  margin: 30px 0 0;
  align-items: end;
}
.nx-cards .nx-card + .nx-card { margin-left: -1px; }

.nx-card {
  padding: 0 var(--nx-pt-pad) 24px;
  border: 1px solid var(--nx-line);
  border-radius: 12px 12px 0 0;
  border-bottom: 0;
  background: transparent;
  display: flex;
  flex-direction: column;
}

.nx-card.pick {
  border-color: var(--nx-ink);
  border-width: 1.5px;
  border-bottom: 0;
  background: var(--nx-surface);
}
/* OPTIONAL, if the ink cap alone reads too quiet. Attio's mechanism, in
   neutral: a 4px ring of the border's own colour at low alpha, first in the
   stack so it sits tight against the 1.5px edge. No layout cost. */
/* .nx-card.pick { box-shadow: 0 0 0 4px rgba(23, 21, 28, .055); } */

/* the head band — same slot on both cards, different weight */
.nx-cardname {
  margin: 0 calc(var(--nx-pt-pad) * -1);
  padding: 0 var(--nx-pt-pad);
  height: 44px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  font-family: var(--nx-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--nx-ink2);
  background: var(--nx-cap);
  border-bottom: 1px solid var(--nx-line);
  border-radius: 11px 11px 0 0;
  min-height: 0;
}
.nx-card.pick .nx-cardname {
  height: 52px;
  margin: 0 calc(var(--nx-pt-pad) * -1);
  color: var(--nx-paper);
  background: linear-gradient(180deg, var(--nx-ink-lift) 0%, var(--nx-ink) 100%);
  border-bottom-color: var(--nx-ink);
  border-radius: 10.5px 10.5px 0 0;
}

.nx-cardbadge {
  margin-left: auto;
  font-size: 9.5px;
  letter-spacing: 0.14em;
  padding: 4px 9px;
  border-radius: 999px;
  color: var(--nx-beam);
  background: color-mix(in srgb, var(--nx-beam) 10%, var(--nx-surface));
  white-space: nowrap;
}
.nx-card.pick .nx-cardbadge {
  color: var(--nx-paper);
  background: rgba(255, 255, 255, 0.12);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

.nx-cardpitch {
  margin: 20px 0 0;
  font-family: var(--nx-serif);
  font-size: 15.5px;
  line-height: 1.42;
  color: var(--nx-ink2);
  min-height: 2.84em;
}

/* --- 3. the price -------------------------------------------------------- */

.nx-cardprice {
  margin: 22px 0 0;
  display: flex;                    /* baseline-flex: the reference pattern */
  align-items: baseline;
  gap: 9px;
  line-height: .9;
  white-space: nowrap;
  animation: nx-restamp .22s cubic-bezier(.2, .7, .3, 1) both;
}
.nx-cardnow {
  font-size: 52px; font-weight: 700; letter-spacing: -.045em;
  color: var(--nx-ink);
  font-variant-numeric: lining-nums;   /* proportional, NOT tabular — see notes */
  font-feature-settings: 'lnum' 1;
  margin-left: -.022em;                /* optical: currency sidebearing flush left */
}
.nx-cardper {
  font-size: 15px; font-weight: 500;
  letter-spacing: -.005em; color: var(--nx-ink3);
}

/* THE SIGNATURE: the superseded figure */
.nx-cardwas {
  position: relative;
  top: -.62em;                      /* raised inside the baseline-flex row */
  font-family: var(--nx-mono);
  font-size: 15px;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--nx-ink3);
  text-decoration: none;            /* we draw the rule ourselves */
}
.nx-cardwas::after {
  content: '';
  position: absolute;
  left: -3px;
  right: -3px;
  top: 50%;
  height: 1.5px;
  border-radius: 1px;
  background: var(--nx-ink3);
  transform: rotate(-6.5deg);
  transform-origin: center;
}
.nx-card.pick .nx-cardwas { color: var(--nx-ink2); }
.nx-card.pick .nx-cardwas::after { background: var(--nx-ink2); }

@keyframes nx-restamp {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

.nx-cardbilled {
  margin: 12px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--nx-ink3);
  min-height: 2.9em;
}
.nx-cardbilled b { font-weight: 600; color: var(--nx-ink2); }

.nx-cardcta {
  margin-top: 6px;
  align-self: stretch;
  text-align: center;
  padding-top: 15px;
  padding-bottom: 15px;
  font-size: 15px;
}
.nx-cardtrial {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--nx-ink3);
}

/* --- 4. the buttons ------------------------------------------------------ */
/* NO translateY ANYWHERE. Fourteen premium pricing pages were measured for
   this pass and not one of them lifts its CTA on hover. The premium hover is
   a background step of 8-35/255 plus a shadow that opens. The lift is the
   tell of a template. */
.nx-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14.5px; font-weight: 500; line-height: 1.15;
  padding: 12px 20px; border-radius: 8px;
  text-decoration: none; border: 1px solid transparent;
  cursor: pointer; font-family: inherit;
  /* split durations: the shadow settles before the colour does */
  transition:
    background-color .18s ease,
    border-color .18s ease,
    color .18s ease,
    box-shadow .12s ease;
}
.nx-btn.big { font-size: 16px; padding: 14px 26px; }

/* The five-layer penumbra: alpha RISES as offset FALLS, which is what a real
   contact shadow does. One blurred blob is what a fake one does. */
.nx-btn.solid {
  background: var(--nx-ink); border-color: var(--nx-ink); color: var(--nx-paper);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, .10),   /* top specular edge */
    inset 0 0 0 1px rgba(255, 255, 255, .04),   /* rim light */
    0 4px 3px 0 rgba(23, 21, 28, .02),
    0 2px 2px 0 rgba(23, 21, 28, .05),
    0 1px 1px 0 rgba(23, 21, 28, .08),
    0 0   1px 0 rgba(23, 21, 28, .10);
}
.nx-btn.solid:hover {
  background: var(--nx-ink-lift); border-color: var(--nx-ink-lift);
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, .14),
    inset 0 0 0 1px rgba(255, 255, 255, .06),
    0 6px 5px 0 rgba(23, 21, 28, .03),
    0 3px 3px 0 rgba(23, 21, 28, .06),
    0 1px 1px 0 rgba(23, 21, 28, .10),
    0 0   1px 0 rgba(23, 21, 28, .12);
}
.nx-btn.solid:active {
  background: var(--nx-ink-press); border-color: var(--nx-ink-press);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .40);   /* light moves inside */
  transition-duration: .06s;
}

.nx-btn.ghost {
  background: var(--nx-surface); color: var(--nx-ink);
  border-color: var(--nx-edge);
  box-shadow: 0 1px 1px 0 rgba(23, 21, 28, .04), 0 0 1px 0 rgba(23, 21, 28, .06);
}
.nx-btn.ghost:hover {
  border-color: var(--nx-ink);
  box-shadow: 0 2px 2px 0 rgba(23, 21, 28, .04), 0 1px 1px 0 rgba(23, 21, 28, .07);
}
.nx-btn.ghost:active {
  background: #f1efea;
  box-shadow: inset 0 1px 3px rgba(23, 21, 28, .12);
  transition-duration: .06s;
}

.nx-btn:focus-visible { outline: 2px solid var(--nx-beam); outline-offset: 2px; }
.nx-btn:disabled,
.nx-btn:disabled:hover {
  background: #f0eff3; border-color: var(--nx-line); color: var(--nx-ink3);
  cursor: not-allowed; box-shadow: none;
}


/* --- 5. the switch ------------------------------------------------------- */

.nx-terms {
  margin: 30px 0 6px;
  background: var(--nx-surface);
  box-shadow: inset 0 1px 2px rgba(23, 21, 28, 0.05);
  /*
    THE BASIS IS STATED, because `auto` resolved to zero.

    `.nx-switches` became a flex row in this pass, which blockifies these
    `inline-flex` tracks into flex items. Their `flex-basis: auto` then falls
    back to `width: auto`, and for a flex container whose own children are
    flex items that came out as a base size of 0 — the currency track measured
    8px wide, its padding and borders alone, with three 44px buttons hanging
    out to the right of it.

    `max-content` is also the honest statement: a segmented control is exactly
    as wide as its buttons, and it is never the thing in a row that gives.
  */
  flex: 0 0 max-content;
}
.nx-term { transition: color 0.14s ease, background-color 0.14s ease; }
.nx-term.on {
  background: var(--nx-ink);
  color: var(--nx-paper);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 3px rgba(23, 21, 28, 0.3);
}

/* --- 6. the table: one lit channel from card head to table foot ----------- */

.nx-ptwrap {
  max-width: var(--nx-pt-max);
  position: relative;
}
.nx-ptwrap::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 33%;
  background: var(--nx-surface);
  border-radius: 0 0 12px 12px;
  box-shadow: 0 20px 36px -28px rgba(23, 21, 28, 0.4);
  pointer-events: none;
}
.nx-pt {
  position: relative;
  border-top: 1px solid var(--nx-ink);
}
.nx-pt tbody tr:not(.nx-pt-group) td { background: transparent; }
.nx-pt tbody tr:not(.nx-pt-group) td + td { border-left: 1px solid var(--nx-line); }

.nx-pt-group th {
  padding: 34px 0 9px;
  font-family: var(--nx-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--nx-ink);
  font-weight: 500;
  border-bottom: 1px solid var(--nx-hair2);
}
.nx-pt tbody:first-of-type .nx-pt-group th { padding-top: 26px; }

.nx-pt tbody tr:not(.nx-pt-group) th,
.nx-pt tbody tr:not(.nx-pt-group) td {
  padding: 15px var(--nx-pt-pad) 16px;
  border-bottom: 1px solid var(--nx-line);
  vertical-align: top;
}
.nx-pt tbody:last-of-type tr:last-child th,
.nx-pt tbody:last-of-type tr:last-child td {
  border-bottom: 0;
  padding-bottom: 26px;
}

.nx-pt-what {
  width: var(--nx-pt-label);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--nx-ink2);
  transition: color 0.12s ease;
}
.nx-pt-val {
  display: block;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.25;
  color: var(--nx-ink);
  font-variant-numeric: tabular-nums;
}
.nx-pt-note {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--nx-ink3);
}
.nx-pt-same .nx-pt-val { font-weight: 500; color: var(--nx-ink2); }

/* Not included. Vercel renders this at FULL body colour and weight so the eye
   scans a level grid; Attio leaves the cell empty; Persona writes a word. A
   greyed-out dash is the one option none of the fourteen picked, so this sits
   between: the character stays, at the note's colour and a text weight, never
   at the 600 of a real value. */
.nx-pt-val.none {
  font-weight: 400;
  font-size: 17px;
  color: var(--nx-ink3);
}

.nx-pt tbody tr:not(.nx-pt-group):hover > * {
  box-shadow: inset 0 0 0 200px rgba(23, 21, 28, 0.028);
}
.nx-pt tbody tr:not(.nx-pt-group):hover .nx-pt-what { color: var(--nx-ink); }

/* --- 7. the FAQ ---------------------------------------------------------- */

.nx { interpolate-size: allow-keywords; }

.nx-faq { margin: 56px 0 0; max-width: var(--nx-pt-max); }
.nx-faqh {
  margin: 0 0 6px;
  font-size: 22px;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--nx-ink);
}

.nx-ask {
  position: relative;
  border-top: 1px solid var(--nx-line);
  transition: border-color 0.18s ease;
}
.nx-ask:last-of-type { border-bottom: 1px solid var(--nx-line); }
.nx-ask:hover { border-top-color: var(--nx-hair2); }
.nx-ask::before {
  content: '';
  position: absolute;
  left: -18px;
  top: -1px;
  bottom: 0;
  width: 2px;
  background: var(--nx-ink);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.nx-ask[open]::before { opacity: 1; }

.nx-ask summary {
  list-style: none;
  cursor: pointer;
  padding: 17px 44px 17px 0;
  position: relative;
  font-size: 15.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--nx-ink2);
  transition: color 0.14s ease;
}
.nx-ask summary::-webkit-details-marker { display: none; }
.nx-ask summary:hover,
.nx-ask[open] summary { color: var(--nx-ink); }

.nx-ask summary::before,
.nx-ask summary::after {
  content: '';
  position: absolute;
  right: 6px;
  top: 50%;
  background: var(--nx-ink3);
  border-radius: 1px;
  transition: transform 0.22s cubic-bezier(0.2, 0.7, 0.3, 1), opacity 0.18s ease,
    background-color 0.14s ease;
}
.nx-ask summary::before { width: 13px; height: 1.5px; margin-top: -0.75px; }
.nx-ask summary::after { width: 1.5px; height: 13px; right: 11.75px; margin-top: -6.5px; }
.nx-ask summary:hover::before,
.nx-ask summary:hover::after { background: var(--nx-ink); }
.nx-ask[open] summary::before { transform: rotate(180deg); }
.nx-ask[open] summary::after { transform: rotate(90deg); opacity: 0; }
.nx-ask summary:focus-visible { outline: 2px solid var(--nx-beam); outline-offset: 2px; }

.nx-ask p {
  margin: 0;
  padding: 0 60px 20px 0;
  font-family: var(--nx-serif);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--nx-ink2);
  max-width: 62ch;
}
/* Guarded at no-preference rather than undone in a reduce block, so the
   transition is never declared for a reader who asked for no motion. */
@media (prefers-reduced-motion: no-preference) {
  .nx-ask::details-content {
    block-size: 0;
    overflow: clip;
    opacity: 0;
    transition: block-size 0.26s cubic-bezier(0.2, 0.7, 0.3, 1), opacity 0.2s ease,
      content-visibility 0.26s allow-discrete;
  }
  .nx-ask[open]::details-content { block-size: auto; opacity: 1; }
}

/* --- 8. motion --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .nx-btn,
  .nx-term,
  .nx-ask,
  .nx-ask summary,
  .nx-ask summary::before,
  .nx-ask summary::after,
  .nx-ask::before,
  .nx-pt-what { transition-duration: 0.01ms; }
  .nx-cardprice { animation: none; }
}

/* --- 9. narrow ----------------------------------------------------------- */

@media (max-width: 860px) {
  .nx-cards { grid-template-columns: 1fr; gap: 16px; margin-bottom: 30px; }
  .nx-cards-corner { display: none; }
  .nx-cards .nx-card + .nx-card { margin-left: 0; }
  .nx-cards .nx-card { border-radius: 12px; }
  .nx-card { border-bottom: 1px solid var(--nx-line); }
  .nx-card.pick { border-bottom: 1.5px solid var(--nx-ink); }
  .nx-ptwrap::before { display: none; }
  .nx-pt { table-layout: auto; }
  .nx-pt tbody tr:not(.nx-pt-group) td + td { border-left: 0; }
  .nx-ask p { padding-right: 0; }
  .nx-ask::before { left: -12px; }
  .nx-cardpitch, .nx-cardbilled { min-height: 0; }
  .nx-shared ul { columns: 1; }
  .nx-cardnow { font-size: 46px; }
}

@media (max-width: 640px) {
  /* Full width here, so the basis has to be released again. */
  .nx-terms { width: 100%; justify-content: stretch; flex: 1 1 100%; }
  .nx-term { flex: 1; justify-content: center; text-align: center; min-height: 44px; }
  .nx-terms.cur { width: auto; flex: 0 0 max-content; }
  .nx-terms.cur .nx-term { flex: 0 0 auto; min-width: 56px; }
  .nx-switches { gap: 12px; }
}
/*
 * THE PLATFORM MOCK'S STYLESHEET.
 *
 * Source: "Inkstand — The Platform", claude.ai/code/artifact/2fc77248.
 *
 * ---------------------------------------------------------------------------
 * THIS IS A COPY OF THE WHOLE FILE, NOT AN EXTRACTION
 * ---------------------------------------------------------------------------
 *
 * Earlier versions ran a parser over the artifact and emitted the rules it
 * matched. Every defect in this file so far came from that one decision:
 *
 *   - the parser read `/* platform additions *\/ .topnav` as a single selector
 *     and skipped the rule, taking 21 others that followed comments with it —
 *     `.topnav { display:flex }` among them, so the masthead wrapped;
 *   - a hand-written drop list threw away `.wrap`, the measure every screen is
 *     composed against, and the element resets, as "document furniture".
 *
 * Neither was a hard problem. Both were the result of writing code to decide
 * what to keep, when the correct amount of deciding was none.
 *
 * So: the artifact's two style blocks, concatenated, with exactly four kinds of
 * textual substitution applied and nothing else. Rules the app never uses come
 * along too — `.cover`, `.cap`, `.wizard` — because leaving them in costs
 * nothing and choosing between them is how this went wrong four times.
 *
 * ---------------------------------------------------------------------------
 * THE SUBSTITUTIONS, IN FULL
 * ---------------------------------------------------------------------------
 *
 *   :root          -> .mockroot        the palette scopes to the signed-in
 *                                      shell, so it cannot reach the marketing
 *                                      site or the studios
 *   body           -> .mockroot        the shell is the app's body
 *   *              -> .mockroot *      keep the box-sizing reset inside
 *   h1..h5, p, svg -> .mockroot <el>   same, and these are type decisions
 *
 * If a rule here looks wrong, it is wrong in the artifact. Fix it there.
 */

@layer components {

.mockroot{
  --paper:#F4F3F6;--surface:#FFFFFF;--surface-2:#FAFAFC;--surface-3:#F0EFF3;
  --line:#E4E2E9;--line-soft:#EFEEF3;--line-strong:#D3D0DB;
  --ink:#17151C;--ink-2:#4A4655;--ink-3:#655F73;--ink-4:#6E6880;
  --flag:#D6006E;--flag-bright:#FF2E8E;--flag-wash:#FDEBF4;
  --beam:#0B756F;--beam-wash:#E8F3F2;
  --cleared:#5B7A2E;--cleared-wash:#F0F4E7;
  --judge:#6D5B8F;--judge-wash:#F2EFF7;
  --r-sm:6px;--r:10px;--r-lg:16px;
  --shadow-2:0 1px 2px rgba(23,21,28,.04),0 4px 16px rgba(23,21,28,.05);
  --shadow-3:0 2px 4px rgba(23,21,28,.04),0 14px 44px rgba(23,21,28,.10);
  --grad-surface:linear-gradient(168deg,var(--surface-2),var(--surface) 70%);
  --sans:'Switzer','Avenir Next',system-ui,-apple-system,'Segoe UI',sans-serif;
  --serif:'Charter','Iowan Old Style','Palatino Linotype',Palatino,Georgia,serif;
  --mono:'SF Mono','Menlo',ui-monospace,'Cascadia Mono',monospace;
}
@media (prefers-color-scheme:dark){.mockroot{
  --paper:#0E0D12;--surface:#16151C;--surface-2:#1B1A22;--surface-3:#201E28;
  --line:#2A2833;--line-soft:#211F2A;--line-strong:#3A3746;
  --ink:#F0EEF4;--ink-2:#BDB8C8;--ink-3:#A8A2B8;--ink-4:#8D8799;
  --flag:#FF2E8E;--flag-bright:#FF5AA5;--flag-wash:#2C0D1E;
  --beam:#22E0D5;--beam-wash:#0C2523;--cleared:#B8F04A;--cleared-wash:#1B2410;
  --judge:#B49BE8;--judge-wash:#1F1A2B;
  --shadow-2:0 1px 2px rgba(0,0,0,.4),0 4px 16px rgba(0,0,0,.3);
  --shadow-3:0 2px 4px rgba(0,0,0,.4),0 14px 44px rgba(0,0,0,.5);}}
[data-theme="dark"] .mockroot{
  --paper:#0E0D12;--surface:#16151C;--surface-2:#1B1A22;--surface-3:#201E28;
  --line:#2A2833;--line-soft:#211F2A;--line-strong:#3A3746;
  --ink:#F0EEF4;--ink-2:#BDB8C8;--ink-3:#A8A2B8;--ink-4:#8D8799;
  --flag:#FF2E8E;--flag-bright:#FF5AA5;--flag-wash:#2C0D1E;
  --beam:#22E0D5;--beam-wash:#0C2523;--cleared:#B8F04A;--cleared-wash:#1B2410;
  --judge:#B49BE8;--judge-wash:#1F1A2B;
  --shadow-2:0 1px 2px rgba(0,0,0,.4),0 4px 16px rgba(0,0,0,.3);
  --shadow-3:0 2px 4px rgba(0,0,0,.4),0 14px 44px rgba(0,0,0,.5);}
[data-theme="light"] .mockroot{
  --paper:#F4F3F6;--surface:#FFFFFF;--surface-2:#FAFAFC;--surface-3:#F0EFF3;
  --line:#E4E2E9;--line-soft:#EFEEF3;--line-strong:#D3D0DB;
  --ink:#17151C;--ink-2:#4A4655;--ink-3:#655F73;--ink-4:#6E6880;
  --flag:#D6006E;--flag-bright:#FF2E8E;--flag-wash:#FDEBF4;
  --beam:#0B756F;--beam-wash:#E8F3F2;--cleared:#5B7A2E;--cleared-wash:#F0F4E7;
  --judge:#6D5B8F;--judge-wash:#F2EFF7;
  --shadow-2:0 1px 2px rgba(23,21,28,.04),0 4px 16px rgba(23,21,28,.05);
  --shadow-3:0 2px 4px rgba(23,21,28,.04),0 14px 44px rgba(23,21,28,.10);}

.mockroot *{box-sizing:border-box;min-width:0}
.mockroot{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
.mockroot h1,.mockroot h2,.mockroot h3,.mockroot h4,.mockroot h5{text-wrap:balance;margin:0;font-weight:600;letter-spacing:-.02em}
.mockroot p{margin:0}svg{display:block}
.wrap{max-width:1120px;margin:0 auto;padding:0 32px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.eyebrow{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4)}
.ico{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.ico.s{width:13px;height:13px}
/*
 * THE MARKS LEAK OUT OF THE APP, SO THEY CARRY THEIR OWN COLOURS.
 *
 * These three are NOT scoped to `.mockroot` — they are used on the public
 * checker too, which is outside the app shell and defines `--color-flag` rather
 * than `--flag`. An undefined custom property inside a SHORTHAND is invalid at
 * computed-value time, so `text-decoration: underline wavy var(--flag)` did not
 * degrade to an uncoloured underline: the whole declaration was dropped and
 * only `text-decoration-thickness` survived. The product's signature mark was
 * invisible on its own public page, silently, exactly as the head of this file
 * warns about unresolved vars.
 *
 * The fallback chain resolves in either world and ends in a literal, so no
 * future page can lose them by not defining a token.
 */
.mark-decided{text-decoration:underline wavy var(--flag,var(--color-flag,#FF2E8E));
  text-decoration-thickness:1.5px; text-underline-offset:5px}
.mark-judge{border-left:1.5px solid var(--beam,var(--color-beam,#22E0D5));
  border-right:1.5px solid var(--beam,var(--color-beam,#22E0D5));padding:0 3px}
.mark-cite{font-family:var(--mono);font-size:9px;vertical-align:super;
  color:var(--ink-4,var(--color-ink-400,#857F93));padding:0 1px}

.cover{padding:66px 0 26px}
.brandline{display:flex;align-items:center;gap:11px;margin-bottom:34px}
.brandline span{font-size:19px;font-weight:600;letter-spacing:-.02em}
.cover h1{font-size:clamp(36px,5vw,58px);line-height:1.04;letter-spacing:-.035em;max-width:17ch}
.cover .sub{margin-top:18px;font-size:17px;color:var(--ink-2);max-width:62ch}
.cover .meta{margin-top:22px;display:flex;flex-wrap:wrap;gap:6px 22px;
  font-family:var(--sans);font-size:11.5px;color:var(--ink-3)}
.cover .meta b{color:var(--ink);font-weight:500}

.stage{padding:16px 0 54px}
.cap{display:flex;align-items:baseline;justify-content:space-between;gap:18px;
  margin-bottom:13px;flex-wrap:wrap}
.cap h2{font-size:22px;letter-spacing:-.028em}
.cap .n{font-family:var(--sans);font-size:11px;color:var(--flag);font-weight:600}
.cap .why{font-size:13px;color:var(--ink-3)}

.mockwrap{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;box-shadow:var(--shadow-3)}
.mockbar{display:flex;align-items:center;gap:8px;padding:10px 15px;background:var(--surface);
  border-bottom:1px solid var(--line)}
.mockbar .dot{width:9px;height:9px;border-radius:50%;background:var(--line);flex:none}
.mockbar .url{margin-left:10px;font-family:var(--mono);font-size:11px;color:var(--ink-4)}
.mock{overflow-x:auto}.mockinner{min-width:900px}
.page{padding:32px 30px 36px}
.phead h3{font-size:26px;letter-spacing:-.028em}
.phead .lede{margin-top:6px;color:var(--ink-2);font-size:14.5px;max-width:66ch}

.btn{padding:8px 15px;border-radius:var(--r-sm);font-size:13.5px;font-weight:600;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.btn.pri{background:var(--ink);color:var(--surface);border-color:var(--ink)}
.btn.gh{background:transparent;border-color:transparent;color:var(--ink-3)}
.btn.sm{padding:5px 11px;font-size:12.5px}
.btn.lg{padding:11px 22px;font-size:15px}
/* The one button in this language whose colour carries information rather than
   emphasis: it destroys something and nothing brings it back. Never drawn in a
   row beside an ordinary control — `RemovalRow` puts it under a rule, on its
   own line, because a Delete sitting between Rename and Duplicate is pressed by
   accident and this product's deletes cascade. */
.btn.stop{border-color:var(--flag);color:var(--flag);background:var(--surface)}
.btn.stop:hover:not(:disabled){background:var(--flag-wash)}
.pill{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;
  font-family:var(--sans);font-size:9.5px;font-weight:500}
.pill.flag{background:var(--flag-wash);color:var(--flag)}
.pill.judge{background:var(--judge-wash);color:var(--judge)}
.pill.ok{background:var(--cleared-wash);color:var(--cleared)}
.pill.beam{background:var(--beam-wash);color:var(--beam)}
.pill.mut{background:var(--line-soft);color:var(--ink-3)}

/* stage 0 */
.seed{max-width:600px;margin:26px auto 0}
.field{margin-bottom:16px}
.field label{font-family:var(--sans);font-size:10px;
  color:var(--ink-4);display:block;margin-bottom:6px}
.inp{width:100%;padding:12px 15px;border:1px solid var(--line-strong);border-radius:var(--r-sm);
  background:var(--surface);color:var(--ink);font-size:15px;text-align:left}
.inp.ph{color:var(--ink-4)}
.chips{display:flex;gap:7px;flex-wrap:wrap}
.chip{padding:8px 15px;border:1px solid var(--line);border-radius:999px;font-size:13.5px;
  background:var(--surface);color:var(--ink-2);font-weight:500}
.chip.on{background:var(--ink);color:var(--surface);border-color:var(--ink)}
.chip.add{border-style:dashed;border-color:var(--line-strong);color:var(--ink-3)}
.dropline{margin-top:20px;padding:15px;border:1.5px dashed var(--line-strong);
  border-radius:var(--r);background:var(--grad-surface);display:flex;align-items:center;
  gap:12px;justify-content:center;font-size:13.5px;color:var(--ink-3)}
.fmts{display:flex;gap:5px;flex-wrap:wrap;justify-content:center;margin-top:11px}
.fmt{font-family:var(--mono);font-size:9.5px;padding:3px 8px;border-radius:4px;
  background:var(--surface-3);color:var(--ink-3);letter-spacing:.04em}

.lane.locked{background:linear-gradient(168deg,var(--surface-3),var(--surface) 58%);
  border-style:dashed;border-color:var(--line-strong)}
.lane.locked .jn{color:var(--ink-3)}
.lock{width:13px;height:13px;border-radius:3px;border:1.5px solid var(--ink-4);flex:none;
  position:relative}
.lock::after{content:"";position:absolute;left:2.5px;top:-3.5px;width:6px;height:5px;
  border:1.5px solid var(--ink-4);border-bottom:0;border-radius:3px 3px 0 0}
.pricetag{margin-top:15px;padding-top:14px;border-top:1px solid var(--line-soft);
  display:flex;align-items:center;justify-content:space-between;gap:12px}
.pricetag .pp{font-size:13px;color:var(--ink-2)}
.pricetag .pp b{color:var(--ink)}
/* signup */
.signup{max-width:430px;margin:0 auto}
.steps{display:flex;gap:6px;margin-bottom:24px;justify-content:center}
.steps i{height:3px;width:38px;border-radius:2px;background:var(--line);display:block}
.steps i.on{background:var(--ink)}
.card2{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:13px 15px;display:flex;align-items:center;gap:11px;margin-bottom:9px}
.card2 .cc{font-family:var(--mono);font-size:13px;color:var(--ink-2);flex:1}
.terms{background:var(--grad-surface);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 16px;margin-top:16px}
.terms div{font-size:12.5px;color:var(--ink-2);padding:4px 0 4px 20px;position:relative}
.terms div::before{content:"";position:absolute;left:5px;top:11px;width:6px;height:6px;
  border-radius:50%;background:var(--cleared)}
.carry{background:linear-gradient(168deg,var(--cleared-wash),var(--surface) 62%);
  border:1px solid var(--line);border-radius:var(--r);padding:15px 17px;margin-bottom:20px}
.carry .cn2{font-size:13.5px;font-weight:600;margin-bottom:7px;display:flex;align-items:center;gap:8px}
.carry ul{margin:0;padding-left:19px}
.carry li{font-size:12.5px;color:var(--ink-2);margin-bottom:3px}

/* wizard */
.wiz{padding:34px 30px 44px;background:var(--surface)}
.steps{display:flex;gap:6px;justify-content:center;margin-bottom:44px}
.steps i{height:3px;width:44px;border-radius:2px;background:var(--line);display:block}
.steps i.on{background:var(--ink)}
.wizbody{max-width:440px;margin:0 auto;text-align:center}
.wizbody.wide{max-width:760px;text-align:left}
.wizart{width:120px;height:84px;margin:0 auto 26px;display:block}
.wizbody h3{font-size:29px;letter-spacing:-.03em;margin-bottom:24px}
.wizbody.wide h3{font-size:25px;margin-bottom:18px}
.wizfield{max-width:400px;margin:0 auto}
.wizfield .inp{font-size:17px;padding:14px 17px;text-align:center}
.cur{display:inline-block;width:1.5px;height:19px;background:var(--flag);
  vertical-align:-3px;margin-left:2px}
.wizhint{font-size:12.5px;color:var(--ink-4);margin-top:14px}
.bigdrop{border:1.5px dashed var(--line-strong);border-radius:var(--r-lg);padding:30px 24px;
  background:var(--grad-surface);text-align:center}
.fanned{position:relative;height:78px;margin-bottom:14px}
.fanned .dfile{position:absolute;left:50%;top:0}
.fanned .f1{transform:translateX(-50%) rotate(-11deg) translateX(-40px)}
.fanned .f2{transform:translateX(-50%);z-index:2}
.fanned .f3{transform:translateX(-50%) rotate(11deg) translateX(40px)}
.bigdroptext{font-size:16px;font-weight:600;margin-bottom:12px}

/* doc illustrations */
.dfile{width:52px;height:66px;border-radius:5px;position:relative;flex:none;
  box-shadow:var(--shadow-2);overflow:hidden;background:var(--surface);
  border:1px solid var(--line)}
.dfile .corner{position:absolute;top:0;right:0;width:17px;height:17px;
  background:var(--surface-3);clip-path:polygon(0 0,100% 100%,100% 0)}
.dfile .band{position:absolute;left:0;top:0;bottom:0;width:4px}
.dfile .lines{position:absolute;left:10px;right:8px;top:26px;display:flex;
  flex-direction:column;gap:3.5px}
.dfile .lines i{height:2.5px;border-radius:1.5px;background:var(--ink-4);opacity:.35;display:block}
.dfile .ext{position:absolute;left:9px;top:9px;font-family:var(--mono);font-size:7px;
  font-weight:700;letter-spacing:.05em}
.dfile.scan .lines i{opacity:.14}
.dfile.scan::after{content:"";position:absolute;inset:22px 8px 8px 10px;border-radius:2px;
  background:repeating-linear-gradient(135deg,var(--ink-4) 0 2px,transparent 2px 5px);opacity:.16}
/* crawl map */
.crawl{position:relative;height:196px;background:var(--grad-surface);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.cnode{position:absolute;display:flex;align-items:center;gap:7px;padding:5px 10px;
  border-radius:999px;background:var(--surface);border:1px solid var(--line);
  font-family:var(--mono);font-size:9.5px;color:var(--ink-3);white-space:nowrap;
  box-shadow:var(--shadow-2)}
.cnode.root{background:var(--ink);color:var(--surface);border-color:var(--ink);font-weight:600}
.cnode.hit{border-color:var(--cleared);color:var(--cleared)}
.cnode i{width:6px;height:6px;border-radius:2px;display:block;flex:none}
/* multi doc */
.docgrid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:11px}
.dcard2{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:14px;display:flex;flex-direction:column;gap:11px}
.dcard2.add{border-style:dashed;border-color:var(--line-strong);align-items:center;
  justify-content:center;background:var(--grad-surface);min-height:150px;color:var(--ink-3)}
.dcard2 .dn3{font-size:12.5px;font-weight:600;line-height:1.3}
.dcard2 .dm3{font-family:var(--sans);font-size:9px;color:var(--ink-4);margin-top:4px}

/* draft review */
.draftbar{display:flex;align-items:center;gap:13px;padding:13px 16px;border-radius:var(--r);
  background:linear-gradient(102deg,var(--judge-wash),var(--surface) 54%);
  border:1px solid var(--line);position:relative;overflow:hidden;margin-bottom:16px}
.draftbar::before{content:"";position:absolute;left:0;top:11px;bottom:11px;width:2px;
  border-radius:2px;background:var(--judge)}
.draftbar .dt{flex:1;font-size:13.5px}
.draftbar .dt b{font-weight:600}
.rrow{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 16px;margin-bottom:8px;display:grid;grid-template-columns:1fr auto;
  gap:14px;align-items:start}
.rrow.off{opacity:.45}
/* WHERE A RULE COMES FROM — shape, not colour.
   reg  = the outside world. A solid rail. You did not write it and cannot reword it.
   own  = your own material. A segmented rail — made of the documents you gave us. */
.rrow{position:relative;padding-left:22px}
.rrow::before{content:"";position:absolute;left:9px;top:15px;bottom:15px;width:3px;border-radius:2px}
.rrow.reg::before{background:var(--ink-3)}
.rrow.own::before{background:repeating-linear-gradient(180deg,
  var(--beam) 0 7px,transparent 7px 11px)}
.rrow.mine::before{background:repeating-linear-gradient(180deg,
  var(--judge) 0 3px,transparent 3px 6px)}
.srcline{display:flex;align-items:center;gap:7px;font-family:var(--sans);font-size:9px;
  color:var(--ink-4);margin-bottom:6px}
.srcline b{color:var(--ink-3);font-weight:600}
.rrow .rn2{font-size:14px;font-weight:600;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rrow .rq{font-family:var(--serif);font-size:13px;color:var(--ink-2);margin-top:6px;
  border-left:2px solid var(--beam);padding-left:11px;line-height:1.5}
.prov{display:flex;align-items:center;gap:7px;margin-top:9px;flex-wrap:wrap}
.provchip{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:999px;
  background:var(--surface-3);font-family:var(--sans);font-size:9.5px;
  color:var(--ink-3)}
.provchip b{color:var(--ink);font-weight:600}
.provchip .pd2{width:6px;height:6px;border-radius:2px;flex:none}
.racts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
/* source tree */
.tree{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:18px 20px}
.tnode{display:flex;align-items:center;gap:11px;padding:9px 0;border-top:1px solid var(--line-soft)}
.tnode:first-of-type{border-top:0}
.tnode.sub{padding-left:26px;position:relative}
.tnode.sub::before{content:"";position:absolute;left:9px;top:0;bottom:50%;width:1px;
  background:var(--line-strong)}
.tnode.sub::after{content:"";position:absolute;left:9px;top:50%;width:10px;height:1px;
  background:var(--line-strong)}
.tnode .tn2{flex:1;font-size:13.5px}
.tnode .tn2 span{font-family:var(--sans);font-size:10.5px;color:var(--ink-4);display:block;margin-top:2px}
.tnode .tc{font-family:var(--sans);font-size:10.5px;color:var(--ink-3)}
/* multi doc */
.docgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px}
.dcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:14px}
.dcard.add{border-style:dashed;border-color:var(--line-strong);display:flex;
  flex-direction:column;align-items:center;justify-content:center;gap:8px;color:var(--ink-3);
  background:var(--grad-surface);min-height:104px}
.dcard .dn2{font-size:13px;font-weight:600;line-height:1.3}
.dcard .dm2{font-family:var(--sans);font-size:9.5px;color:var(--ink-4);margin-top:5px}
.dcard .db{margin-top:9px;display:flex;align-items:center;gap:6px}

/* two lanes */
.lanes{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:22px}
.lane{border:1px solid var(--line);border-radius:var(--r-lg);padding:19px;background:var(--surface)}
.lane.now{background:linear-gradient(168deg,var(--cleared-wash),var(--surface) 58%)}
.lane.working{background:linear-gradient(168deg,var(--beam-wash),var(--surface) 58%)}
.lane .lh{display:flex;align-items:center;gap:9px;margin-bottom:4px}
.lane .lt{font-size:15px;font-weight:600}
.lane .ls{font-size:12.5px;color:var(--ink-3);margin-bottom:14px}
.job{display:flex;align-items:center;gap:10px;padding:9px 0;border-top:1px solid var(--line-soft)}
.job:first-of-type{border-top:0}
.job .jn{flex:1;font-size:13.5px}
.job .jm{font-family:var(--sans);font-size:10px;color:var(--ink-4)}
.spin{width:12px;height:12px;border-radius:50%;border:1.5px solid var(--line-strong);
  border-top-color:var(--beam);flex:none}
.tick{width:13px;height:13px;color:var(--cleared);flex:none}

/* brand card */
.brandcard{display:flex;align-items:center;gap:16px;padding:17px 19px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);margin-top:20px}
/* `position:relative` is load-bearing, not tidiness. The logo inside a mark is
   `position:absolute; inset:0`, so without a positioned ancestor here it
   resolved against the page and painted the brand's logo across the whole
   screen, on every screen. `.av` has always had it; this rule never did. */
.brandcard .mark2{width:46px;height:46px;border-radius:12px;flex:none;display:grid;
  place-items:center;color:#fff;font-family:var(--sans);font-size:15px;font-weight:600;
  position:relative;overflow:hidden}
.brandcard .bn{font-size:17px;font-weight:600}
.brandcard .bm{font-family:var(--sans);font-size:11px;color:var(--ink-4);margin-top:3px}
.swatches{display:flex;gap:5px;margin-left:auto}
.swatches i{width:26px;height:26px;border-radius:6px;display:block;border:1px solid rgba(0,0,0,.06)}

/* found list */
.found{display:flex;flex-direction:column;gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);border-radius:var(--r);overflow:hidden;margin-top:16px}
.found div{background:var(--surface);padding:11px 14px;display:flex;align-items:center;
  gap:11px;font-size:13.5px}
.found .fsrc{font-family:var(--sans);font-size:10px;color:var(--ink-4);margin-left:auto}

/* quotes */
.q{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:15px 17px;margin-bottom:10px}
.q.fresh{background:linear-gradient(102deg,var(--beam-wash),var(--surface) 52%)}
.quote{font-family:var(--serif);font-size:15.5px;line-height:1.5;color:var(--ink);
  border-left:3px solid var(--beam);padding-left:14px}
.derived{margin-top:11px;padding-top:11px;border-top:1px solid var(--line-soft);
  display:flex;align-items:center;justify-content:space-between;gap:12px}
.derived .dn{font-size:13.5px;font-weight:600}
.derived .dl{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4);margin-bottom:3px}

/* toast */
.toast{position:relative;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-3);padding:17px 19px;max-width:430px;
  display:flex;gap:13px;align-items:flex-start;overflow:hidden}
.toast::before{content:"";position:absolute;left:0;top:13px;bottom:13px;width:2px;
  border-radius:2px;background:var(--beam)}
.toast .tt{font-size:14px;font-weight:600;margin-bottom:4px}
.toast p{font-size:13px;color:var(--ink-2);line-height:1.5}

/* editor */
.editor{display:grid;grid-template-columns:1.5fr 1fr;min-height:320px}
.sheet{padding:32px 36px;border-right:1px solid var(--line);background:var(--surface)}
.sheet .doc{font-family:var(--serif);font-size:19px;line-height:1.85;color:var(--ink);max-width:46ch}
.caret{display:inline-block;width:1.5px;height:19px;background:var(--flag);
  vertical-align:-3px;margin-left:1px}
.side{padding:20px;background:var(--surface-2)}
.live{display:flex;align-items:center;gap:8px;font-family:var(--sans);font-size:10.5px;
  color:var(--cleared);margin-bottom:14px}
.live i{width:6px;height:6px;border-radius:50%;background:var(--cleared);display:block}
.find{border:1px solid var(--line);border-radius:var(--r);padding:13px;margin-bottom:9px;
  background:var(--surface);position:relative;overflow:hidden}
.find.hot{background:linear-gradient(140deg,var(--flag-wash),var(--surface) 58%)}
.find.hot::before{content:"";position:absolute;left:0;top:10px;bottom:10px;width:2px;
  border-radius:2px;background:var(--flag)}
.find .fh{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:5px}
.find .ft{font-size:13px;font-weight:600}
.find p{font-size:12.5px;color:var(--ink-2);line-height:1.55}
.find .src{margin-top:8px;padding-top:8px;border-top:1px solid var(--line-soft);
  font-family:var(--sans);font-size:10px;color:var(--ink-4)}

.tiers{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);border-radius:var(--r);overflow:hidden;margin-top:20px}
.tiers div{background:var(--surface);padding:13px 14px}
.tiers .tv{font-size:23px;font-weight:600;letter-spacing:-.03em;line-height:1;
  font-variant-numeric:tabular-nums}
.tiers .tk{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4);margin-top:5px}
.tiers .td2{font-size:11px;color:var(--ink-3);margin-top:4px;line-height:1.4}

.callout{background:var(--grad-surface);border:1px solid var(--line);border-radius:var(--r);
  padding:16px 18px;margin:18px 0;position:relative;overflow:hidden}
.callout::before{content:"";position:absolute;left:0;top:12px;bottom:12px;width:2px;border-radius:2px}
.callout.info::before{background:var(--beam)}
.callout.stop{background:linear-gradient(102deg,var(--flag-wash),var(--surface) 56%)}
.callout.stop::before{background:var(--flag)}
.callout.judge{background:linear-gradient(102deg,var(--judge-wash),var(--surface) 56%)}
.callout.judge::before{background:var(--judge)}
.callout .ct{font-size:13.5px;font-weight:600;margin-bottom:5px}
.callout p{font-size:13.5px;color:var(--ink-2);max-width:76ch}

section.notes{padding:44px 0;border-top:1px solid var(--line)}
section.notes h2{font-size:23px;margin-bottom:8px;letter-spacing:-.028em}
section.notes .sd{font-size:14.5px;color:var(--ink-2);max-width:74ch;margin-bottom:20px}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}
.nc{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:17px}
.nc h4{font-size:14.5px;margin-bottom:6px}
.nc p{font-size:13.5px;color:var(--ink-2);line-height:1.55}
.mockroot table{width:100%;border-collapse:collapse;margin:14px 0;font-size:13px}
.mockroot th{text-align:left;font-family:var(--sans);font-size:9.5px;
  color:var(--ink-4);padding:0 11px 8px 0;font-weight:500;
  border-bottom:1px solid var(--line)}
.mockroot td{padding:9px 11px 9px 0;border-bottom:1px solid var(--line-soft);color:var(--ink-2);
  vertical-align:top}
td b{color:var(--ink);font-weight:600}
.tblwrap{overflow-x:auto}
.foot{padding:30px 0 76px;color:var(--ink-3);font-size:13.5px}
.foot b{color:var(--ink)}
@media(max-width:860px){.wrap{padding:0 20px}.lanes,.editor{grid-template-columns:1fr}
  .tiers{grid-template-columns:1fr 1fr}}


/* platform additions */
.topnav{display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:11px 22px;background:var(--surface);border-bottom:1px solid var(--line)}
.topnav .left{display:flex;align-items:center;gap:20px}
.tabs{display:flex;gap:2px}
.tab{padding:6px 11px;border-radius:7px;font-size:13px;color:var(--ink-3);font-weight:500;
  display:flex;align-items:center;gap:6px}
.tab.on{background:var(--beam-wash);color:var(--beam);font-weight:600}
.switcher{display:flex;align-items:center;gap:9px;padding:5px 10px;border:1px solid var(--line);
  border-radius:8px;font-size:13px;font-weight:600}
.av{border-radius:50%;display:grid;place-items:center;font-family:var(--sans);font-size:10px;
  font-weight:600;color:#fff;width:27px;height:27px;flex:none;position:relative}
.av.sm{width:21px;height:21px;font-size:8.5px}
.av .on2{position:absolute;right:-1px;bottom:-1px;width:8px;height:8px;border-radius:50%;
  background:var(--cleared);border:2px solid var(--surface)}
.stack{display:flex}.stack .av{border:2px solid var(--surface);margin-left:-7px}
.stack .av:first-child{margin-left:0}
.frames{display:flex;gap:4px}
/*
 * A DECK AND A DOCUMENT, TOLD APART WITHOUT BEING READ.
 *
 * `.fdeck` wraps the deck tile so the edges of the frames behind it have
 * somewhere to sit; the padding on the right reserves that room rather than
 * letting the edges overlap whatever is beside the thumbnail. `.docblock` is
 * the same footprint in the opposite material — pale paper with rules on it,
 * against the deck's saturated card. The two read as different objects at a
 * glance, which is the whole point of them.
 */
.fdeck{position:relative;flex:none;padding-right:7px;display:inline-flex}
.fstack{position:absolute;top:3px;bottom:3px;right:0;width:11px;border-radius:0 4px 4px 0;
  z-index:1;opacity:.5;box-shadow:var(--shadow-2)}
.fstack:nth-of-type(2){right:3px;opacity:.3}
.fdeck .frame{position:relative;z-index:2}
.docblock{width:50px;height:64px;border-radius:5px;overflow:hidden;position:relative;flex:none;
  display:flex;flex-direction:column;justify-content:flex-start;gap:4px;padding:8px 7px;
  background:var(--surface);border:1px solid var(--line-strong);box-shadow:var(--shadow-2)}
.docblock i{display:block;height:2px;border-radius:1px;background:var(--ink-4);opacity:.42}
/* `.dbh` / `.dbs`, not `.h` / `.s`. `editor/bench.css` declares a GLOBAL,
   unscoped `.h` for the canvas selection handle — `position:absolute`, 9x9,
   `var(--beam)` — and it was winning here, so the document's heading rule drew
   as a teal square floating out of the tile. Only the rendered page showed it;
   the component test passed throughout. */
.docblock i.dbh{height:4px;width:76%;opacity:.72;margin-bottom:2px}
.docblock i.dbs{width:52%}
.frame{width:50px;height:64px;border-radius:5px;overflow:hidden;position:relative;flex:none;
  display:flex;flex-direction:column;justify-content:flex-end;padding:6px;box-shadow:var(--shadow-2)}
.frame .ft2{font-size:6.5px;font-weight:700;color:#fff;line-height:1.2}
.frame .fb2{position:absolute;top:4px;right:4px;width:11px;height:11px;border-radius:50%;
  display:grid;place-items:center;background:var(--flag-bright);color:#fff;font-size:6.5px;font-weight:700}
.wrow2{display:grid;grid-template-columns:56px 1fr 130px 118px 74px;gap:14px;align-items:center;
  padding:11px 15px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  margin-bottom:7px;position:relative;overflow:hidden}
.wrow2.hot{background:linear-gradient(100deg,var(--flag-wash),var(--surface) 46%)}
.wrow2.hot::before{content:"";position:absolute;left:0;top:11px;bottom:11px;width:2px;
  border-radius:2px;background:var(--flag)}
.wrow2 .nm2{font-size:13.5px;font-weight:600}
.wrow2 .sub2{font-family:var(--sans);font-size:10px;color:var(--ink-4);margin-top:3px;
  display:flex;align-items:center;gap:6px}
.bandh{display:flex;align-items:center;justify-content:space-between;margin:22px 0 10px}
.bandh h4{font-size:13px;display:flex;align-items:center;gap:7px}
.bandh .c2{font-family:var(--sans);font-size:10.5px;color:var(--ink-4)}
.bar{display:flex;height:9px;border-radius:5px;overflow:hidden;background:var(--line-soft)}
.bar i{display:block;height:100%}
.crow2{display:grid;grid-template-columns:190px 1fr 110px 70px;gap:16px;align-items:center;
  padding:13px 17px;border-top:1px solid var(--line-soft)}
.crow2:first-child{border-top:0}
.crow2 .who2{display:flex;align-items:center;gap:10px}
.board{display:grid;grid-template-columns:88px repeat(4,1fr);gap:7px}
.bh2{font-family:var(--sans);font-size:9.5px;
  color:var(--ink-4);padding-bottom:5px}
.chanlab{font-family:var(--sans);font-size:10px;color:var(--ink-3);display:flex;align-items:center;
  gap:6px;padding-right:6px}
.cell{background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:8px;
  min-height:94px;display:flex;flex-direction:column;gap:6px;position:relative}
.cell.f{background:linear-gradient(168deg,var(--flag-wash),var(--surface) 62%)}
.cell.j{background:linear-gradient(168deg,var(--judge-wash),var(--surface) 62%)}
.cell.c{background:linear-gradient(168deg,var(--cleared-wash),var(--surface) 62%)}
.cell.empty{background:transparent;border-style:dashed;align-items:center;justify-content:center}
.cell .cn2{font-size:11px;font-weight:600;line-height:1.25}
.cell .cm2{font-family:var(--sans);font-size:9px;color:var(--ink-4);display:flex;
  align-items:center;justify-content:space-between;gap:5px;margin-top:auto}
.cell .pres{position:absolute;top:-7px;right:-5px;z-index:3}
.copyblock{height:30px;border-radius:4px;padding:5px 6px;display:flex;flex-direction:column;
  gap:2.5px;justify-content:center;background:var(--surface-2);border:1px solid var(--line-soft)}
.copyblock i{height:2.5px;border-radius:1.5px;background:var(--ink-4);opacity:.4;display:block}
.spark{display:flex;align-items:flex-end;gap:1.5px;height:15px}
.spark i{width:3px;border-radius:1px;display:block}
/* benchmark */
.bmrow{display:grid;grid-template-columns:180px 1fr 70px;gap:14px;align-items:center;
  padding:11px 0;border-top:1px solid var(--line-soft)}
.bmrow:first-of-type{border-top:0}
.bmrow .bl{font-size:13px;font-weight:600}
.bmtrack{height:22px;border-radius:5px;background:var(--surface-3);position:relative;overflow:hidden}
.bmtrack .you{position:absolute;left:0;top:0;bottom:0;border-radius:5px;
  background:linear-gradient(96deg,var(--beam-wash),var(--surface))}
.bmtrack .you::after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:var(--beam)}
.bmtrack .med{position:absolute;top:-3px;bottom:-3px;width:1.5px;background:var(--ink);z-index:2}
.bmtrack .med span{position:absolute;top:-15px;left:50%;transform:translateX(-50%);
  font-family:var(--sans);font-size:8.5px;color:var(--ink);white-space:nowrap}
.bmv{font-family:var(--sans);font-size:12px;text-align:right;font-variant-numeric:tabular-nums}

/* A 180px label and a 70px value are 278px of fixed track before the bar
   starts, which panned this screen 172px sideways on a 390px phone. Below the
   breakpoint the label sits over its own bar and the number rides beside it. */
@media (max-width: 640px){
  /*
   * Rows that pair content with an action.
   *
   * `.rrow` is `1fr auto` and `.tnode` is a nowrap flex line, so on a phone the
   * action column sat past the right edge and the page panned — 59px on the
   * desk, 26px on Work, 3px on Rules. Grid and flex children default to
   * `min-width:auto`, which is what stops the text half shrinking, so the
   * min-width reset is doing the work and the wrap is what catches the rest.
   */
  .mockroot .rrow{grid-template-columns:minmax(0,1fr)}
  /* 190+110+70 plus three 16px gaps is 418px of fixed track in a 328px
     column, which is where the desk's 59px pan came from. */
  .mockroot .crow2{grid-template-columns:minmax(0,1fr) auto;gap:6px 12px}
  .mockroot .crow2 > *{min-width:0}

  /* 56+130+118+74 plus four gaps is 434px of fixed track. The later rule at
     line ~729 widens the last column to auto, which does not help at 390px. */
  .mockroot .wrow2{grid-template-columns:auto minmax(0,1fr);gap:8px 12px}
  .mockroot .wrow2 > *{min-width:0}

  /* A baseline flex line ending in a button, which had nowhere to go. */
  .mockroot .advicerow{flex-wrap:wrap}
  .mockroot .advicerow > *{min-width:0}
  .mockroot .racts{justify-content:flex-start}
  .mockroot .tnode{flex-wrap:wrap}
  .mockroot .tnode > *{min-width:0}
  .mockroot .tc{margin-left:0}

  .mockroot .bmrow{grid-template-columns:1fr auto;gap:6px 10px}
  .mockroot .bmrow .bl{grid-column:1;font-size:14px}
  .mockroot .bmrow .bmv{grid-column:2;grid-row:1}
  .mockroot .bmrow .bmtrack{grid-column:1 / -1}
}
.bmv.up{color:var(--cleared)}.bmv.dn{color:var(--flag)}
/* pdf preview */
.pdfprev{background:var(--surface);border:1px solid var(--line);border-radius:6px;
  box-shadow:var(--shadow-3);padding:20px 22px;aspect-ratio:1/1.414;overflow:hidden;
  display:flex;flex-direction:column;gap:9px}
.pdfprev .ph2{font-size:11px;font-weight:700;letter-spacing:-.01em}
.pdfprev .psub{font-family:var(--mono);font-size:6.5px;color:var(--ink-4);letter-spacing:.06em}
.pdfprev .prule{border-left:2px solid var(--beam);padding-left:6px}
.pdfprev .prule.reg{border-left-color:var(--ink-3)}
.pdfprev .pn{font-size:7px;font-weight:600}
.pdfprev .pq{font-family:var(--serif);font-size:6px;color:var(--ink-3);line-height:1.4;margin-top:2px}
.pdfprev .pbar{height:5px;border-radius:2px;background:var(--surface-3);position:relative}
.pdfprev .pbar i{position:absolute;left:0;top:0;bottom:0;border-radius:2px;background:var(--beam);display:block}
.pdfstack{position:relative}
.pdfstack .pdfprev:nth-child(2){position:absolute;inset:0;transform:rotate(-3deg) translate(-8px,4px);z-index:-1;opacity:.5}


/*
 * ---------------------------------------------------------------------------
 * THE ONE RULE IN THIS FILE THAT IS NOT THE ARTIFACT'S
 * ---------------------------------------------------------------------------
 *
 * In the artifact every screen sits inside `.wrap { max-width:1120px }`, then
 * inside `.mockwrap`, which is a drawing of a browser window. The app itself —
 * `.mockinner` — is edge to edge within that frame, about 1056px across. So the
 * design was composed at roughly 1056px and never had to answer what happens at
 * 2000px, because in the artifact nothing ever is.
 *
 * A real product has no frame around it. Rendered without a measure, every
 * `.wrow2` ran the full width of the display: a title at one end, a Review
 * button at the other, and a metre of white between them. That is not what the
 * design looks like, but neither is it something the design states.
 *
 * So this is a judgement, marked as one. It takes `.wrap`'s own number rather
 * than inventing a third. If the intent is full-bleed, delete this block — the
 * rest of the file is untouched artifact.
 */
/*
 * ---------------------------------------------------------------------------
 * NO MEASURE. THE ARTIFACT CAPS NOTHING AND NEITHER DOES THIS.
 * ---------------------------------------------------------------------------
 *
 * A rule here capped `.page` at 1120px, borrowed from `.wrap` — which in the
 * artifact bounds the DOCUMENT, not the app. The app inside that document is
 * `.mockinner`, and it is edge to edge within its frame at close to 1800px.
 * Every screen was therefore being drawn narrower than the design it was being
 * compared against, and the board suffered worst: four cells and a channel
 * label squeezed into two thirds of the width they were composed at.
 *
 * `.page` already carries the artifact's own `32px 30px 36px`. That is the
 * spacing the design specifies and it is now the only spacing there is.
 */

/*
 * ---------------------------------------------------------------------------
 * DISCLOSURE, BORROWED FROM THE SIBLING ARTIFACT
 * ---------------------------------------------------------------------------
 *
 * "The Platform" specifies no drawer. "Design Direction" does, and specifies it
 * for exactly this: a rule row opens into `.drawer` holding `.prose` for the
 * wording and `.dgrid` for its facts, with the open row marked.
 *
 * Taken from there rather than invented here. Same designer, same tokens, same
 * product — and the alternative was a disclosure pattern chosen in the app,
 * which is the thing that has gone wrong every time.
 *
 * Two names differ between the two files and are rewritten so the copy
 * resolves: `--radius`/`--radius-lg` are `--r`/`--r-lg` here, and
 * `--shadow-lg` is `--shadow-3`. An unresolved var in CSS is not an error —
 * it silently computes to nothing, so a straight paste would have produced a
 * drawer with no radius and no shadow and no warning anywhere.
 */
.mockroot .drawer { background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg); box-shadow:var(--shadow-3); padding:18px; margin:0 3px 3px }
.mockroot .drawer .dh { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin-bottom:12px }
.mockroot .drawer h4 { font-size:16px }
.mockroot .prose { font-family:var(--serif); font-size:15px; line-height:1.6; color:var(--ink-2); padding:13px 15px; background:var(--surface-2); border-radius:var(--r); border-left:3px solid var(--flag); max-width:66ch }
.mockroot .dgrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(132px,1fr)); gap:1px; background:var(--line-soft); border:1px solid var(--line-soft); border-radius:var(--r); overflow:hidden; margin-top:13px }
.mockroot .dgrid div { background:var(--surface); padding:10px 12px }
.mockroot .dgrid .k { font-family:var(--sans); font-size:9px; color:var(--ink-4) }
.mockroot .dgrid .v { font-size:12.5px; margin-top:3px; font-weight:500 }

/*
 * A DISABLED CONTROL THAT LOOKS ENABLED.
 *
 * Not in the artifact — the mock draws no disabled state, because nothing in it
 * was ever refused. The product refuses constantly and on purpose: an inherited
 * rule may be tightened and nothing else, which is the guarantee the whole
 * inheritance model rests on.
 *
 * With no rule here, `button:disabled` rendered pixel-identical to a live one.
 * Four controls sat in the rule drawer looking clickable, did nothing when
 * clicked, and said nothing — their reasons were on `title`, which is a tooltip
 * nobody hovers. The screen read as broken software rather than as a refusal,
 * and that is exactly how it was reported.
 *
 * This is a gap the design does not cover rather than a decision it made, which
 * is why it is filled here instead of being argued with.
 */
/*
 * ...AND THE FIX FOR IT WAS ITSELF UNREADABLE.
 *
 * `opacity:.42` was the first answer, and it fails on exactly the control it
 * matters most for. Opacity composites the WHOLE element toward the page, both
 * the label and the ground it sits on, at the same rate. On a primary button
 * that is white text on `--ink` over `--paper`: the label lands near 253 and
 * its ground near 155, which measures about 2.6:1. Screen-verified on
 * `/app/start`, the first screen a new account sees, where "Next" is disabled
 * until the brand has a name.
 *
 * A disabled control still has to be READ — it is unavailable, not absent, and
 * the person has to see what it will say when it turns on. So the state is
 * drawn with its own ground and its own ink, both tokens, and the contrast is
 * a property of the pair rather than a side effect of a filter.
 */
.mockroot .btn:disabled,
.mockroot .btn.pri:disabled,
.mockroot .btn:disabled:hover,
.mockroot .btn.pri:disabled:hover {
  opacity:1;
  cursor:not-allowed;
  background:var(--surface-3);
  border-color:var(--line);
  color:var(--ink-3);
  box-shadow:none;
}


/* =========================================================================
 * CONTRAST, AFFORDANCE, AND A PILL THAT IS NOT AN ALARM
 * =========================================================================
 *
 * Reported directly: "poor contrast", "no affordances for progressive
 * disclosure", "everything is flashing pink".
 *
 * CONTRAST. `--ink-4` is #615C6E on a #16151C surface — about 2.8:1, used at
 * 9–10.5px for source lines, counts and dates. That is below AA for small text
 * by a wide margin, and `.rrow.off` then multiplied it by .45.
 *
 * THE FOUR LINES THAT USED TO BE HERE NEVER APPLIED, AND THAT IS WHY THE
 * TOKENS ARE NOW SET IN THE PALETTE BLOCK ABOVE INSTEAD.
 *
 * They said "raised here rather than in the palette block above, so the lifted
 * artifact stays readable as what it was". The intent was right and the
 * mechanism did not work: the repair was written as `.mockroot { --ink-4:… }`,
 * specificity 0,1,0, while the palette declares the dark values under
 * `[data-theme="dark"] .mockroot`, specificity 0,2,0. The stricter selector
 * won, so in dark mode — which is the default here — `--ink-4` computed to the
 * unrepaired #615C6E for as long as the repair had been in the file. Measured
 * in Chrome, not inferred: `getComputedStyle` on `.mockroot` returned #615C6E
 * for `--ink-4` and #8B8599 for `--ink-3`, both the values this block claimed
 * to have replaced.
 *
 * The second line made it worse in the other direction. It was
 * `:root:not([data-theme="dark"]) .mockroot`, specificity 0,3,0 — the highest
 * of the set — and `:not([data-theme="dark"])` is true whenever the attribute
 * is simply absent, which is every visitor who has never touched a theme
 * control. So a machine set to dark with no stored preference got #7C7689, a
 * tone picked for white paper, on near-black. A repair that lands on neither
 * theme is not a repair, and it read as one for as long as nobody measured it.
 *
 * A token override cannot be appended to the end of a stylesheet when the
 * thing being overridden is declared with a more specific selector. Appending
 * is what produced the bug. The values now sit in the four palette blocks with
 * the rest of the scale, which is the only place they can sit and win.
 *
 * WHAT THE NEW VALUES ARE FOR. Every use of `--ink-4` is text at 14px or
 * smaller, so all of it is subject to 4.5:1 and none of it qualifies for the
 * large-text allowance. The values are the lightest that clear 4.5:1 on the
 * darkest ground each theme puts them on, which is `--surface-3`:
 *
 *   light  #6E6880   5.31:1 on surface, 4.80:1 on paper, 4.64:1 on surface-3
 *   dark   #8D8799   5.23:1 on surface, 5.58:1 on paper, 4.74:1 on surface-3
 *
 * `--ink-3` takes the values the dead block intended, which do apply now:
 *
 *   light  #655F73   6.11:1 on surface, 5.34:1 on surface-3
 *   dark   #A8A2B8   7.36:1 on surface, 6.67:1 on surface-3
 *
 * THAT LEAVES INK-3 AND INK-4 CLOSER TOGETHER THAN THEY WERE, ON PURPOSE.
 *
 * The gap between them used to be large because ink-4 was below the floor of
 * legibility; there is no way to keep a fourth grey that is meaningfully
 * lighter than ink-3 AND readable, because 4.5:1 is where the room runs out.
 * A step that can only be told apart from its neighbour by being unreadable
 * was never a step in a hierarchy. What separates them is size: ink-4 is
 * metadata at 10.5–11px, ink-3 is secondary text at 12–13.5px. Both are in the
 * UI sans now — mono is for identifiers, so it cannot be the difference.
 *
 * PINK. `--flag` means SOMETHING NEEDS ATTENDING TO. It was carrying "Stops a
 * release", which is a permanent property of most rules in a regulated
 * account — so a healthy rule set flashed pink end to end and a real alert had
 * nothing left to say. Severity is weight now: `.strong` is solid, `.quiet` is
 * barely there, and pink is spent only on a rule that has caught nothing.
 * ========================================================================= */

/* Dimmed, not erased. .45 over already-low contrast was unreadable, and the
   "Turned off" section heading now carries the meaning the opacity was. */
.mockroot .rrow.off { opacity:.72 }

/* A brand-scoped tab on an account with no brands. All five fall back to the
   same brand-list screen, so the tab row stops pretending they are live —
   still in the DOM, still clickable, visibly not yet doors. Same floor as
   .rrow.off, for the same legibility reason. */
.mockroot .tab.off { opacity:.55 }

/* Severity as weight. Neither of these is a state colour. */
.mockroot .pill.strong { background:var(--ink); color:var(--surface); font-weight:600 }
.mockroot .pill.quiet { background:transparent; color:var(--ink-3); box-shadow:inset 0 0 0 1px var(--line-strong) }

/* A PILL YOU CAN PRESS SAYS SO. Same shape, plus the two things that make a
   control read as one: it responds to the pointer, and it takes focus. */
.mockroot .pillbtn { cursor:pointer; border:0; transition:filter .12s, box-shadow .12s }
.mockroot .pillbtn:hover:not(:disabled) { filter:brightness(1.14); box-shadow:0 0 0 3px var(--line-soft) }
.mockroot .pillbtn:disabled { cursor:default; opacity:1; color:var(--ink-3); background:var(--surface-3); border-color:var(--line) }
.mockroot .pillbtn:focus-visible { outline:2px solid var(--beam); outline-offset:2px }

/* THE RULE ITSELF, WHICH IS ALSO THE FIELD.
   Serif because it is regulated wording, at a size that is meant to be read
   rather than scanned past. The editable variant shows an edit affordance on
   hover instead of relying on somebody guessing the text is a control. */
.mockroot .rulesentence { font-family:var(--serif); font-size:15px; line-height:1.55;
  color:var(--ink); margin-top:7px; max-width:74ch }
.mockroot .rulesentence.editable { cursor:text; border-radius:var(--r-sm);
  margin-left:-7px; padding:3px 7px; transition:background .12s, box-shadow .12s }
.mockroot .rulesentence.editable:hover { background:var(--surface-2);
  box-shadow:inset 0 0 0 1px var(--line) }
.mockroot .rulesentence.editable:hover::after { content:"  ✎"; color:var(--ink-4); font-size:12px }
.mockroot .rulesentence.editable:focus-visible { outline:2px solid var(--beam); outline-offset:1px }
textarea.mockroot-sentence, .mockroot textarea.rulesentence { width:100%; max-width:74ch;
  margin-top:7px; padding:9px 11px; resize:vertical }


/* A FILTER BAR THAT IS ONE OBJECT, not six controls in a row that wraps badly.
   Named areas so the search keeps the full width on a phone and the two dates
   stay beside each other instead of splitting across lines. */
.mockroot .filterbar { display:grid; gap:8px; margin:14px 0 4px;
  grid-template-areas:"q q k a f t s"; grid-template-columns:2fr 0 1.1fr 1.3fr .9fr .9fr auto;
  align-items:center }
.mockroot .filterbar .inp { padding:8px 11px; font-size:13px }
.mockroot .filterbar select.inp { cursor:pointer }
@media (max-width:900px){
  .mockroot .filterbar { grid-template-areas:"q q" "k a" "f t" "s s";
    grid-template-columns:1fr 1fr }
}


/* The last column of a waiting row was 74px — exactly one button — and adding
   "Hand on" beside Review made the two overlap. `overflow:hidden` also clipped
   the handover menu, which opens downward out of the row. Both are consequences
   of the row gaining an action it did not have in the artifact. */
.mockroot .wrow2 { grid-template-columns:56px 1fr 130px 118px auto; overflow:visible }


/* =========================================================================
 * PAGE IDENTITY — see `PageHead` in design/parts.tsx for the argument.
 *
 * Six tabs all rendered `.phead` → `.bandh` → rows, so every screen read the
 * same at a glance. Colour cannot be the differentiator here: it is entirely
 * spoken for by state. These give a screen a silhouette instead — an eyebrow
 * in a fixed slot, a mark, and the two or three FIGURES that only that screen
 * would ever show.
 * ========================================================================= */
.mockroot .pagehead { display:flex; align-items:flex-start; justify-content:space-between;
  gap:28px; flex-wrap:wrap; padding-bottom:18px; margin-bottom:6px;
  border-bottom:1px solid var(--line) }
.mockroot .pagehead :is(h1,h2,h3) { font-size:27px; letter-spacing:-.028em; margin-top:7px; text-wrap:balance }
.mockroot .pagehead .lede { margin-top:7px; color:var(--ink-2); font-size:14.5px; max-width:62ch }
.mockroot .pagehead-act { margin-left:auto; align-self:center }

.mockroot .eyebrow { display:flex; align-items:center; gap:7px; font-family:var(--sans);
  font-size:9.5px; color:var(--ink-4) }

/* The numbers, big enough to read before the heading. Tabular so a column of
   them does not shift as they change. */
.mockroot .figures { display:flex; gap:26px; align-items:flex-start; padding-top:4px }
.mockroot .figure { min-width:64px }
.mockroot .figure .fn { font-size:30px; font-weight:600; letter-spacing:-.03em; line-height:1;
  font-variant-numeric:tabular-nums; color:var(--ink) }
.mockroot .figure .fn.flag { color:var(--flag) }
.mockroot .figure .fn.judge { color:var(--judge) }
.mockroot .figure .fn.ok { color:var(--cleared) }
.mockroot .figure .fn.mut { color:var(--ink-3) }
.mockroot .figure .fo { font-family:var(--sans); font-size:9px;
  color:var(--ink-4); margin-top:7px; max-width:11ch; line-height:1.4 }

@media (max-width:760px){
  .mockroot .pagehead { gap:16px }
  .mockroot .figures { gap:18px }
  .mockroot .figure .fn { font-size:24px }
}


/* A GRID OF DESTINATIONS, not another list of rows.
   The account screen is the one place in the product that is a map rather than
   a queue — nothing here is work, it is where things live. Rows made it read as
   a sixth version of every other screen; cards give it a shape of its own and
   let the unbuilt ones sit quietly instead of taking a full-width line each. */
.mockroot .cardgrid { display:grid; gap:10px; margin-top:4px;
  grid-template-columns:repeat(auto-fit,minmax(248px,1fr)) }
.mockroot .navcard { display:flex; flex-direction:column; gap:7px; padding:16px 17px;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  text-decoration:none; color:inherit; min-height:124px; position:relative;
  transition:border-color .12s, transform .12s }
.mockroot a.navcard:hover { border-color:var(--line-strong); transform:translateY(-1px) }
.mockroot .navcard .nch { display:flex; align-items:center; gap:8px; font-size:14.5px;
  font-weight:600; letter-spacing:-.012em }
.mockroot .navcard .ncw { font-size:12.5px; line-height:1.5; color:var(--ink-3) }
.mockroot .navcard.off { border-style:dashed; background:transparent }
.mockroot .navcard .ncgo { margin-top:auto; font-family:var(--sans); font-size:9.5px;
  color:var(--ink-4) }
.mockroot a.navcard:hover .ncgo { color:var(--beam) }


/* =========================================================================
 * THE TRAY, ATTACHED — and avatars you can actually see
 * =========================================================================
 *
 * `.drawer` sat under a row as a separate card with its own border, radius and
 * shadow, so opening a rule produced two objects instead of one object opening.
 * It now joins the row: the row loses its bottom corners while open, the tray
 * loses its top ones, the seam between them goes, and the tray sits on a
 * BRIGHTER surface so it reads as the inside of the thing rather than another
 * thing beside it.
 * ========================================================================= */
.mockroot .rrow.open { margin-bottom:0; border-bottom-left-radius:0; border-bottom-right-radius:0;
  border-bottom-color:transparent }
.mockroot .drawer.attached { margin:0 0 10px; border-top:0;
  border-top-left-radius:0; border-top-right-radius:0;
  background:var(--surface-3); box-shadow:none; padding:16px 17px 17px }
/* The rail continues through the tray, so the provenance of the row you opened
   does not stop at the fold. */
.mockroot .drawer.attached.reg, .mockroot .drawer.attached.own,
.mockroot .drawer.attached.mine { position:relative; padding-left:26px }
.mockroot .drawer.attached::before { content:""; position:absolute; left:9px; top:0; bottom:16px;
  width:3px; border-radius:2px }
.mockroot .drawer.attached.reg::before { background:var(--ink-3) }
.mockroot .drawer.attached.own::before { background:repeating-linear-gradient(180deg,
  var(--beam) 0 7px,transparent 7px 11px) }
.mockroot .drawer.attached.mine::before { background:repeating-linear-gradient(180deg,
  var(--judge) 0 3px,transparent 3px 6px) }

/* AVATARS. 27px and 21px are thumbnail sizes for a face that carries a name,
   an initial and a presence dot. A person is the most identifiable thing on
   most of these rows and was the smallest. */
.mockroot .av { width:34px; height:34px; font-size:11.5px }
.mockroot .av.sm { width:26px; height:26px; font-size:9.5px }
.mockroot .av .on2 { width:9px; height:9px }


/* =========================================================================
 * WHILE YOU WERE AWAY — the one panel that must not be scrolled past.
 * Brighter than a row, and the only surface in the product with a gradient,
 * because it is the only one reporting work the product did on its own.
 * ========================================================================= */
.mockroot .awaycard { background:linear-gradient(135deg,var(--beam-wash),var(--surface) 62%);
  border:1px solid var(--line-strong); border-radius:var(--r-lg); padding:16px 18px 14px;
  margin-bottom:22px }
.mockroot .awayhead { display:flex; align-items:baseline; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:12px }
.mockroot .awaymeta { font-size:9.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-4) }
.mockroot .awayclear { font-size:13.5px; color:var(--ink-2); max-width:70ch }
.mockroot .awaylist { display:flex; flex-direction:column; gap:1px;
  background:var(--line-soft); border:1px solid var(--line-soft); border-radius:var(--r);
  overflow:hidden }
.mockroot .awayitem { display:flex; align-items:center; gap:11px; padding:12px 14px;
  background:var(--surface); text-decoration:none; color:inherit; transition:background .12s }
.mockroot .awayitem:hover { background:var(--surface-3) }
.mockroot .awayitem .awaywhat { display:block; font-size:13.5px; font-weight:600 }
.mockroot .awayitem .awaywhy { display:block; font-size:12.5px; color:var(--ink-3); margin-top:2px }
.mockroot .awayitem .awaycta { margin-left:auto; font-family:var(--sans); font-size:9.5px;
  color:var(--ink-4); white-space:nowrap }
.mockroot .awayitem:hover .awaycta { color:var(--beam) }


/* SUGGESTIONS. One surface, not a card each — a stack of small cards reads as
   five problems; one panel reads as a review of the set. */
.mockroot .advice { border:1px solid var(--line-strong); border-radius:var(--r-lg);
  background:linear-gradient(135deg,var(--judge-wash),var(--surface) 58%);
  padding:14px 16px; margin:16px 0 20px }
.mockroot .advicerow { display:flex; align-items:baseline; gap:12px; padding:9px 0;
  border-top:1px solid var(--line-soft) }
.mockroot .advicerow:first-of-type { border-top:0; padding-top:4px }
.mockroot .advicewhat { font-size:13.5px; font-weight:600 }
.mockroot .advicewhy { font-family:var(--sans); font-size:10px;
  color:var(--ink-4) }
.mockroot .advicego { margin-left:auto; white-space:nowrap }


/* =========================================================================
 * THE PANEL THAT SAYS THE PRODUCT WAS WORKING
 *
 * Loud on purpose. Everything else on the desk is a queue somebody has to get
 * through; this is the one surface reporting work already done, so it leads
 * with a sentence at heading size and a bar showing what was swept.
 *
 * Motion is used for exactly one thing here: making it obvious the sweep
 * HAPPENED. The bar fills, the count runs up, the findings rise in one after
 * another. Nothing loops, nothing bounces, and all of it is off under
 * `prefers-reduced-motion` — a compliance screen that fidgets is a compliance
 * screen nobody trusts.
 * ========================================================================= */
.mockroot .awaycard { background:linear-gradient(135deg,var(--beam-wash) -10%,var(--surface) 55%);
  border:1px solid var(--line-strong); border-radius:var(--r-lg); padding:20px 22px 18px;
  margin-bottom:24px; position:relative; overflow:hidden }

/* The light sweep across the whole panel is gone. It was a flourish rather than
   a micro-interaction: a 1.1s wipe over a compliance summary drew the eye to
   the animation instead of to the finding. What survives is the smallest thing
   that still says the sweep happened — the bar filling, once, quickly. */

.mockroot .awayhead { display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:14px }
.mockroot .awaymeta { font-size:9.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-4); font-variant-numeric:tabular-nums }

/* THE SWEEP BAR — how much was looked at, and how much of it moved. */
.mockroot .awaybar { display:flex; height:5px; border-radius:3px; overflow:hidden;
  background:var(--line-soft); margin-bottom:16px }
.mockroot .awaybar i { display:block; height:100%; transform-origin:left;
  animation:awayFill 380ms cubic-bezier(.2,.7,.3,1) both }
@keyframes awayFill { from { transform:scaleX(0) } to { transform:scaleX(1) } }

/* THE HEADLINE FINDING. Heading size, because it is the answer to the only
   question somebody opens this screen with. */
.mockroot .awaylead { font-size:24px; line-height:1.2; letter-spacing:-.025em; font-weight:600;
  max-width:22ch; text-wrap:balance }
.mockroot .awayleadwhy { font-size:14px; line-height:1.55; color:var(--ink-2);
  margin-top:9px; max-width:62ch }
.mockroot .awaylead-act { margin-top:14px }

.mockroot .awayrest { margin-top:16px; border-top:1px solid var(--line-soft); padding-top:4px }
.mockroot .awayitem { display:flex; align-items:center; gap:11px; padding:11px 0;
  text-decoration:none; color:inherit }
.mockroot .awayitem + .awayitem { border-top:1px solid var(--line-soft) }
.mockroot .awayitem .awaywhat { display:block; font-size:13.5px; font-weight:600 }
.mockroot .awayitem .awaywhy { display:block; font-size:12.5px; color:var(--ink-3); margin-top:2px }
.mockroot .awayitem .awaycta { margin-left:auto; font-family:var(--sans); font-size:9.5px;
  color:var(--ink-4); white-space:nowrap;
  transition:color .12s, transform .12s }
.mockroot .awayitem:hover .awaycta { color:var(--beam); transform:translateX(2px) }
.mockroot .awayclear { font-size:15px; color:var(--ink-2); max-width:62ch }

/* Findings rise in, in order, so the panel reads as arriving rather than being
   there all along. */
/* 3px and 240ms. Enough to register as arriving, not enough to watch. */
.mockroot .rise { animation:riseIn 240ms cubic-bezier(.2,.7,.3,1) both }
.mockroot .rise-1 { animation-delay:40ms }
.mockroot .rise-2 { animation-delay:90ms }
.mockroot .rise-3 { animation-delay:140ms }
@keyframes riseIn { from { opacity:0; transform:translateY(3px) } to { opacity:1; transform:none } }

@media (prefers-reduced-motion:reduce){
  .mockroot .awaybar i, .mockroot .rise { animation:none }
  .mockroot .awayitem:hover .awaycta { transform:none }
}


/* PRECEDENT. Set apart from the rule's own facts because it is not a property
   of the rule — it is what people did about it, and the whole value is noticing
   that somebody already answered this. */
.mockroot .precedent { margin-top:14px; padding:13px 15px; border-radius:var(--r);
  background:var(--surface-2); border:1px solid var(--line-soft) }
.mockroot .precrow + .precrow { margin-top:12px; padding-top:12px;
  border-top:1px solid var(--line-soft) }
.mockroot .precex { font-family:var(--sans); font-size:10px; color:var(--ink-4); margin-top:6px }
.mockroot .precsplit { margin-top:11px; font-size:12.5px; color:var(--judge) }


/* FIRST RUN. Two columns: what you tell it, and what it found. The catch side
   is deliberately the wider one — the point of the screen is the thing it
   noticed, not the form. */
.mockroot .firstgrid { display:grid; gap:30px; grid-template-columns:minmax(280px,1fr) minmax(320px,1.15fr);
  margin-top:22px }
@media (max-width:860px){ .mockroot .firstgrid { grid-template-columns:1fr } }
.mockroot .firstmeta { font-size:10px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-4); margin-top:8px; display:block }

.mockroot .firstwait { border:1px dashed var(--line-strong); border-radius:var(--r-lg);
  padding:22px; min-height:200px }
.mockroot .firstcatch { border:1px solid var(--line-strong); border-radius:var(--r-lg);
  background:linear-gradient(140deg,var(--flag-wash) -20%,var(--surface) 52%); padding:22px 24px }
.mockroot .firstquote { font-family:var(--serif); font-size:21px; line-height:1.5;
  letter-spacing:-.01em; margin:0 0 14px; max-width:34ch }
.mockroot .firstrule { font-size:14px; color:var(--ink-2); max-width:52ch }
.mockroot .firstmore { margin-top:16px; border-top:1px solid var(--line-soft); padding-top:12px }
.mockroot .firstmore summary { font-family:var(--sans); font-size:9.5px;
  color:var(--ink-4); cursor:pointer }
.mockroot .firstmorerow { display:flex; align-items:baseline; gap:9px; margin-top:9px;
  font-size:13px; color:var(--ink-2) }
.mockroot .firstratio { margin-top:18px }
.mockroot .firstbar { display:flex; height:5px; border-radius:3px; overflow:hidden;
  background:var(--line-soft) }
.mockroot .firstbar i { display:block; height:100%; animation:awayFill 380ms cubic-bezier(.2,.7,.3,1) both }


/* AN AREA WITH PARTS. A rail plus a page, so the shape of the area is visible
   from wherever somebody lands rather than only from a menu they came through.

   Named for what it does rather than for the first screen that used it: this
   was `.acctshell` while the account was the only area deep enough to need it,
   and the rule set is the second. See `src/design/rail.tsx`. */
.mockroot .railshell { display:grid; grid-template-columns:196px minmax(0,1fr); gap:30px;
  padding:26px 30px; align-items:start }
.mockroot .railbody { min-width:0 }
.mockroot .railshell > .railbody > .page { padding:0 }
.mockroot .rail { display:flex; flex-direction:column; gap:1px; position:sticky; top:78px }
.mockroot .raillink { display:flex; align-items:center; gap:9px; padding:8px 11px;
  border-radius:var(--r-sm); font-size:13.5px; color:var(--ink-2); text-decoration:none;
  transition:background .12s, color .12s }
.mockroot a.raillink:hover { background:var(--surface-2); color:var(--ink) }
.mockroot .raillink.on { background:var(--surface-3); color:var(--ink); font-weight:600 }
.mockroot .raillink.off { color:var(--ink-4); cursor:default }
.mockroot .raillink em { margin-left:auto; font-family:var(--sans); font-size:8.5px;
  font-style:normal; color:var(--ink-4) }
@media (max-width:820px){
  .mockroot .railshell { grid-template-columns:1fr; gap:16px; padding:20px 18px }
  .mockroot .rail { position:static; flex-direction:row; flex-wrap:wrap; gap:4px }
  /* The rail is a row of chips here, so an entry has to hold together as one:
     without this the label and its count are two flex items on a wrapping line
     and the count can land on the row below, beside somebody else's label. */
  .mockroot .raillink { flex:0 0 auto }
  .mockroot .raillink em { margin-left:5px }
  .mockroot .raillink.off { display:none }
}


.mockroot .subscribed { margin-top:16px; padding:15px 17px; border-radius:var(--r-lg);
  background:var(--surface-2); border:1px solid var(--line) }


/* A provider picture, over the initials rather than instead of them. */
.mockroot .av .avimg { position:absolute; inset:0; width:100%; height:100%;
  border-radius:50%; object-fit:cover }


/* =========================================================================
 * STUDIO — the maker's screen, and it is allowed to look like one.
 *
 * The governance screens are austere and answer-first because they decide
 * whether something may ship. This one is browsable: bigger targets, the shape
 * of each format drawn rather than named, and the surfaces it publishes listed
 * on the card so a writer knows what will be checked before starting.
 * ========================================================================= */
.mockroot .tmplgrid { display:grid; gap:12px; margin-top:4px;
  grid-template-columns:repeat(auto-fit,minmax(228px,1fr)) }
.mockroot .tmpl { display:flex; flex-direction:column; align-items:flex-start; gap:6px;
  padding:16px 17px 15px; text-align:left; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r-lg); cursor:pointer;
  transition:border-color .12s, transform .12s, background .12s }
.mockroot .tmpl:hover:not(:disabled) { border-color:var(--line-strong);
  background:var(--surface-2); transform:translateY(-1px) }
.mockroot .tmpl:disabled { cursor:default; opacity:1; color:var(--ink-3); background:var(--surface-3); border-color:var(--line) }
.mockroot .tmpl:focus-visible { outline:2px solid var(--beam); outline-offset:2px }

/* The format, as a shape. A carousel and a story are not the same object. */
.mockroot .tmplframes { display:flex; gap:3px; margin-bottom:6px; height:34px; align-items:flex-end }
.mockroot .tmplframes i { display:block; width:20px; height:26px; border-radius:3px;
  background:linear-gradient(150deg,var(--tmpl-a,#6D5B8F),
    color-mix(in srgb,var(--tmpl-a,#6D5B8F) 52%,#000));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14); position:relative; overflow:hidden }
/* A suggestion of a headline and a body line, so a card reads as a piece of work
   rather than as an empty placeholder. The first frame carries both because it
   is the cover; the rest carry one. */
.mockroot .tmplframes i::before { content:""; position:absolute; left:3px; right:5px; top:5px;
  height:2.5px; border-radius:1px; background:rgba(255,255,255,.82) }
.mockroot .tmplframes i::after { content:""; position:absolute; left:3px; right:8px; top:10px;
  height:1.5px; border-radius:1px; background:rgba(255,255,255,.42) }
.mockroot .tmplframes i:nth-child(n+2)::after { display:none }
/* `ar-` prefix because a class cannot begin with a digit: `.4-5` parses as a
   number and the production minifier refuses the whole sheet. The dev server's
   parser accepted it, so this only failed at build — which is the argument for
   running the real build before pushing, not after. */
.mockroot .tmplframes.ar-4-5 i { width:21px; height:26px }
.mockroot .tmplframes.ar-1-1 i { width:26px; height:26px }
.mockroot .tmplframes.ar-9-16 i { width:15px; height:30px }
.mockroot .tmplframes.ar-16-9 i { width:34px; height:19px }
/* Six formats, six hues. Grey on grey made a gallery of six identical cards,
   and the first thing a person does here is tell them apart. */
.mockroot .tmplgrid .tmpl:nth-child(6n+1){ --tmpl-a:#2E6BE6 }
.mockroot .tmplgrid .tmpl:nth-child(6n+2){ --tmpl-a:#0F9D77 }
.mockroot .tmplgrid .tmpl:nth-child(6n+3){ --tmpl-a:#E0603A }
.mockroot .tmplgrid .tmpl:nth-child(6n+4){ --tmpl-a:#8B5CF6 }
.mockroot .tmplgrid .tmpl:nth-child(6n+5){ --tmpl-a:#C2410C }
.mockroot .tmplgrid .tmpl:nth-child(6n+6){ --tmpl-a:#0E7490 }
.mockroot .tmpl{ transition:border-color .15s, transform .15s, box-shadow .15s }
.mockroot .tmpl:hover:not(:disabled){ border-color:color-mix(in srgb,var(--tmpl-a) 65%,var(--line));
  transform:translateY(-2px);
  box-shadow:0 10px 26px -16px color-mix(in srgb,var(--tmpl-a) 80%,transparent) }
.mockroot .tmpl:hover:not(:disabled) .tmplframes i { transform:rotate(-1.5deg) }
.mockroot .tmplframes i{ transition:transform .15s }

.mockroot .tmplname { display:flex; align-items:center; gap:7px; font-size:14.5px;
  font-weight:600; letter-spacing:-.012em }
.mockroot .tmplwhere { font-family:var(--sans); font-size:9px;
  color:var(--ink-4) }
.mockroot .tmplwhat { font-size:12.5px; line-height:1.5; color:var(--ink-3) }
/* What gets checked. The one thing a compliance product can put here. */
.mockroot .tmplroles { display:flex; flex-wrap:wrap; gap:4px; margin-top:8px }
.mockroot .tmplroles em { font-family:var(--sans); font-size:8.5px;
  font-style:normal; color:var(--ink-3);
  background:var(--line-soft); border-radius:999px; padding:3px 7px }

}

/* =========================================================================
 * THE TWO STUDIOS
 *
 * They are different products with different canvases — frames against prose —
 * and the screen that launches them showed a flat list of formats followed by
 * a text link, so nobody could tell which one they were opening. Each gets a
 * panel, a colour and a count. The colour is the only place on a maker screen
 * where two accents sit side by side, and it is doing identification rather
 * than decoration: beam for the visual studio, judge for the prose one.
 * ====================================================================== */
.mockroot .studios{display:grid;gap:16px;margin-top:20px;
  grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)}
@media (max-width:900px){ .mockroot .studios{grid-template-columns:minmax(0,1fr)} }

.mockroot .studio{border:1px solid var(--line);border-radius:var(--r-lg);padding:18px;
  background:var(--surface);position:relative;overflow:hidden}
.mockroot .studio::before{content:"";position:absolute;inset:0 0 auto 0;height:2px}
.mockroot .studio.carousel::before{background:var(--beam)}
.mockroot .studio.copy::before{background:var(--judge)}
.mockroot .studio.carousel{background:
  linear-gradient(160deg,color-mix(in srgb,var(--beam) 7%,transparent),var(--surface) 42%)}
.mockroot .studio.copy{background:
  linear-gradient(160deg,color-mix(in srgb,var(--judge) 9%,transparent),var(--surface) 42%)}

.mockroot .studio header{display:flex;align-items:flex-start;gap:11px;margin-bottom:14px}
.mockroot .studio header h3{font-size:17px;font-weight:650;letter-spacing:-.01em}
.mockroot .studio header p{font-size:13.5px;color:var(--ink-2);margin-top:2px}
.mockroot .studio .sdot{width:9px;height:9px;border-radius:50%;flex:none;margin-top:5px}
.mockroot .studio.carousel .sdot{background:var(--beam)}
.mockroot .studio.copy .sdot{background:var(--judge)}
.mockroot .studio .scount{margin-left:auto;font-family:var(--sans);font-size:20px;
  font-weight:600;line-height:1;color:var(--ink-3)}

/* The control this screen was missing entirely: start one, in one click. */
.mockroot .bigstart{width:100%;display:grid;grid-template-columns:auto 1fr;gap:2px 12px;
  align-items:center;text-align:left;padding:15px 16px;border-radius:var(--r);
  border:1px solid color-mix(in srgb,var(--judge) 45%,var(--line));
  background:color-mix(in srgb,var(--judge) 12%,transparent);cursor:pointer;
  transition:border-color .15s,background .15s}
.mockroot .bigstart:hover:not(:disabled){border-color:var(--judge);
  background:color-mix(in srgb,var(--judge) 18%,transparent)}
.mockroot .bigstart:disabled { opacity:1; cursor:not-allowed;
  background:var(--surface-3); border-color:var(--line);
  color:var(--ink-3); box-shadow:none; }
.mockroot .bigstart .ico{grid-row:1 / span 2;width:20px;height:20px;color:var(--judge)}
.mockroot .bigstart span{font-size:15px;font-weight:600}
.mockroot .bigstart em{font-style:normal;font-size:13px;color:var(--ink-2)}

.mockroot .seeall{display:inline-block;margin-top:12px;font-family:var(--sans);
  font-size:11px;color:var(--ink-3);text-decoration:none}
.mockroot .seeall:hover{color:var(--ink)}

/* Work in progress, drawn rather than listed.
 *
 * This was rows of grey text on a screen whose whole job is making things. The
 * `Frame` component already existed and already took a brand accent and a
 * headline; the one screen showing somebody's own work in progress was the one
 * screen not using it. */
.mockroot .wfilters{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:14px 0 4px}
/* `.inp` is width:100% everywhere else, which is right for a form and wrong
   for a toolbar — it put each control on its own row. */
.mockroot .wfilters .inp{width:auto;flex:0 1 auto;min-width:0}
.mockroot .wfilters input[type="search"]{flex:1 1 14rem;min-width:10rem}
.mockroot .wcount{margin-left:auto;color:var(--ink-4)}

.mockroot .wipgrid{display:grid;gap:10px;margin-top:12px;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,260px),1fr))}
.mockroot .wip{display:flex;align-items:center;gap:12px;padding:11px 13px;
  border:1px solid var(--line);border-radius:var(--r);background:var(--surface);
  text-decoration:none;color:inherit;transition:border-color .15s,transform .15s}
.mockroot .wip:hover{border-color:var(--ink-3);transform:translateY(-1px)}
.mockroot .wipbody{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.mockroot .wipname{font-size:14px;font-weight:600;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .wipmeta{font-family:var(--sans);font-size:10px;color:var(--ink-4)}

/* =========================================================================
 * THE WORK LIST
 *
 * The board, the calendar and the contact sheet each used to filter to one
 * campaign, so a piece filed under none was invisible on all three — which is
 * how real work vanished. That is fixed: the rail decides which work, every
 * view draws all of it, and a section that holds work back says so with the
 * count. This table is a table because seven facts per piece are meant to be
 * compared down a column rather than read one card at a time.
 *
 * (The word here was "wave", which was invented vocabulary, removed
 * everywhere, and survived in this comment alone — where it had also stopped
 * being true.)
 * ========================================================================= */
.mockroot .wlistwrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);margin-top:12px}
.mockroot .wlistwrap:focus-visible{outline:2px solid var(--beam);outline-offset:2px}
/* Seven columns do not fit a phone. The region scrolls; the page must not. */
.mockroot table.wlist{min-width:820px;margin:0}
.mockroot .wlist th{padding:11px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
.mockroot .wlist td{padding:9px 14px;vertical-align:middle}
.mockroot .wlist tbody tr:last-child td{border-bottom:none}
.mockroot .wlist tbody tr:hover{background:var(--surface-2)}

/* Row selection. The boxes are furniture for an act most visits never
 * perform, so they hold their column but stay invisible until the pointer is
 * on the row, the focus is in it, or a selection already exists (`.picking`)
 * — at which point every box shows, because a half-visible selection cannot
 * be reviewed before the destructive-ish press. Opacity rather than
 * display:none keeps them clickable targets and keeps the columns from
 * shifting on hover. */
.mockroot .wlist .wlpick{width:34px;padding-right:2px}
/* Screen-reader-only text: the standard clip pattern, scoped like everything
   else. First use is the selection column's header word. */
.mockroot .vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.mockroot .wlpick input{opacity:0;margin:0;cursor:pointer}
.mockroot .wlist tbody tr:hover .wlpick input,
.mockroot .wlist tbody tr:focus-within .wlpick input,
.mockroot .wlist.picking .wlpick input{opacity:1}

/* The bar over the table while anything is selected. The austere register:
 * a count, the act, the way out — no wash, no icon. */
.mockroot .wselbar{display:flex;align-items:center;gap:10px;margin:10px 0 0;
  padding:7px 12px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);color:var(--ink-3)}

.mockroot .wlname{display:flex;align-items:center;gap:11px;text-decoration:none;
  color:var(--ink);font-size:13.5px;font-weight:600;min-width:0}
.mockroot .wlname span{overflow:hidden;text-overflow:ellipsis;max-width:34ch}
.mockroot .wlname:hover span{text-decoration:underline}
/* A thumbnail, not a slide. `.frame` is 50x64 for the board's cells and would
   make every row taller than the text it belongs to. */
.mockroot .wlist .frame{width:26px;height:34px;border-radius:4px}
.mockroot .wlist .frame .ft2{font-size:4px;line-height:1.15}

.mockroot .wlsub{display:block;font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4)}
.mockroot .wlfile{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.mockroot .wlfile .inp{width:auto;min-width:0;font-size:12px;padding:5px 9px;max-width:15rem}

/* The template picker's options, which were raw Tailwind cards on a screen
   otherwise drawn in this stylesheet. Same grid the format gallery uses. */
.mockroot .tmplpick{display:grid;gap:8px;grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))}
.mockroot .tmplopt{text-align:left;padding:11px 13px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--surface);cursor:pointer;display:flex;
  flex-direction:column;gap:3px;transition:border-color .15s}
.mockroot .tmplopt:hover:not(:disabled){border-color:var(--judge)}
.mockroot .tmplopt:disabled { opacity:1; cursor:not-allowed;
  background:var(--surface-3); border-color:var(--line);
  color:var(--ink-3); box-shadow:none; }
.mockroot .tmplopt .tmplname{font-size:13.5px;font-weight:600}
.mockroot .tmplopt .tmplmakes{font-size:13px;color:var(--ink-2);line-height:1.4}

/* Campaign names on this brand run to seventy characters. Left unbounded they
   take half the table and squeeze the seven facts it exists to compare. */
.mockroot .wlcamp{max-width:30ch}
/* A `<select>` sizes itself to its longest option, and the campaign filter's
   longest option is one of those names — it grew to half the toolbar. */
.mockroot .wfilters select.inp{max-width:16rem}

/* Two lines, then an ellipsis. A pharma title runs to ninety characters, and
   inside a 35%-wide column on a phone that is a nine-line row. */
.mockroot .wlname span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  white-space:normal}

@media (max-width: 640px){
  /* THE PHONE COLLAPSE THIS STYLESHEET ALREADY INTENDED, PUT BACK.
   *
   * There is a `.wrow2{grid-template-columns:auto minmax(0,1fr)}` in the 640px
   * block above, with a comment saying the fixed tracks do not fit a phone.
   * A later unconditional rule — `.mockroot .wrow2{grid-template-columns:56px
   * 1fr 130px 118px auto}` — outranks it by order at EVERY width, so the
   * collapse has never applied: 56+130+118 plus four gaps is 360px of fixed
   * track inside a 330px row, and every screen drawing this row scrolled
   * sideways on a phone. Restated here, after that rule, rather than editing
   * it.
   *
   * The action cell also gets a row of its own. In the two-column layout it
   * lands in the `auto` track, which sizes to its content — three buttons wide
   * — and pushed the page to 495px.
   */
  .mockroot .wrow2{grid-template-columns:auto minmax(0,1fr)}
  .mockroot .wrow2 > *{min-width:0}
  .mockroot .wrow2 > *:last-child{grid-column:1 / -1;text-align:left}
  .mockroot .wrow2 .racts{justify-content:flex-start}
}

/* `.copyblock` has no width of its own — it fills a board cell. Inside the
   56px frame track of a `.wrow2` it collapsed to a grey sliver. */
.mockroot .wrow2 .copyblock{width:44px}

/* The lock that means "your seat cannot change this".
 * Four words and a glyph, because role restrictions turn up on half the
 * governance screens and a sentence on each would be a paragraph of apology
 * every time a viewer opens one. */
.mockroot .lockwrap{display:inline-flex;flex-direction:column;align-items:flex-end;gap:5px}
.mockroot .lockbtn{display:inline-flex;align-items:center;gap:6px;padding:4px 9px;
  border:1px solid var(--line);border-radius:999px;color:var(--ink-3);
  background:transparent;cursor:help;transition:color .15s,border-color .15s}
.mockroot .lockbtn:hover{color:var(--ink);border-color:var(--ink-3)}
.mockroot .locknote{max-width:26rem;font-size:13.5px;line-height:1.5;color:var(--ink-2);
  text-align:right}

/* Where an inherited rule can actually be changed. */
.mockroot .rulewhere{font-size:12.5px;color:var(--ink-3);text-decoration:none;
  border-bottom:1px solid var(--line-strong);white-space:nowrap}
.mockroot .rulewhere:hover{color:var(--ink);border-bottom-color:var(--ink-3)}

/* An advice row IS the control, not a paragraph with a button on the end.
 *
 * A row that does something has to LOOK different from one that does not, at
 * rest and not only on hover — hover is unavailable on a touch device and
 * undiscoverable on a mouse until you have already guessed. So an actionable
 * row carries a chevron and its label in the accent, permanently, and a static
 * row carries neither. That is the whole tell, and it is consistent wherever
 * `.advicerow` is used. */
.mockroot button.advicerow,
.mockroot a.advicerow{width:100%;text-align:left;background:transparent;border:0;
  border-top:1px solid var(--line-soft);cursor:pointer;text-decoration:none;color:inherit;
  border-radius:var(--r-sm);transition:background .12s}
.mockroot button.advicerow:first-of-type,
.mockroot a.advicerow:first-of-type{border-top:0}
.mockroot button.advicerow:hover,
.mockroot a.advicerow:hover{background:var(--surface-2)}
.mockroot button.advicerow:hover .advicego,
.mockroot a.advicerow:hover .advicego{color:var(--ink)}
.mockroot .advicego{font-family:var(--sans);font-size:11px;color:var(--beam);
  white-space:nowrap;display:inline-flex;align-items:center;gap:5px}
/* The chevron. Drawn rather than a glyph so it inherits colour and needs no
   sprite lookup inside a row that may repeat fifty times. */
.mockroot .advicego::after{content:"";width:5px;height:5px;flex:none;
  border-top:1.5px solid currentColor;border-right:1.5px solid currentColor;
  transform:rotate(45deg);transition:transform .12s}
.mockroot button.advicerow:hover .advicego::after,
.mockroot a.advicerow:hover .advicego::after{transform:rotate(45deg) translate(1.5px,-1.5px)}
.mockroot button.advicerow:focus-visible,
.mockroot a.advicerow:focus-visible{outline:2px solid var(--beam);outline-offset:2px}


/* =========================================================================
 * ONE DOCUMENT PER ROW, NOT ONE RULE PER ROW
 *
 * The drift band on Signals rendered a card per affected rule, and every card
 * repeated the document name, the status chip and the same forty-word
 * explanation of what that status means. Two adopted sector packs produced
 * sixteen of them; a brand book behind forty rules produces forty. The
 * explanation is a fact about the DOCUMENT, so it is said once, at the top of
 * the document's group, and the rules underneath are a list.
 *
 * The whole header is the button. A row that expands, with a control bolted to
 * its right edge, is two targets for one act — the same defect `.advicerow`
 * above was rebuilt to remove.
 * ========================================================================= */
.mockroot .driftgroup{display:flex;align-items:flex-start;gap:14px;width:100%;
  text-align:left;background:transparent;border:0;padding:0;cursor:pointer;
  color:inherit;border-radius:var(--r-sm);transition:background .12s}
.mockroot .driftgroup:hover{background:var(--surface-2)}
.mockroot .driftgroup:focus-visible{outline:2px solid var(--beam);outline-offset:3px}
.mockroot .driftgroup > span:first-child{display:block;min-width:0}

/* Said once per document. Muted, because a reader who has met this sentence
   on the group above does not need it shouted on the next one. */
.mockroot .drifthow{display:block;margin-top:5px;max-width:62ch;font-size:13.5px;
  line-height:1.5;color:var(--ink-3)}

.mockroot .driftcount{margin-left:auto;display:inline-flex;align-items:center;gap:8px;
  white-space:nowrap;font-family:var(--sans);font-size:11px;
  color:var(--beam)}
/* Duplicates are a defect in the rule set, so they are flagged rather than
   toned down — but they are not an alarm, so they stop short of --flag. */
.mockroot .driftcount b{font-weight:600;color:var(--judge)}
.mockroot .driftchev{width:6px;height:6px;flex:none;border-top:1.5px solid currentColor;
  border-right:1.5px solid currentColor;transform:rotate(135deg);
  transition:transform .12s}
.mockroot .driftgroup[aria-expanded="true"] .driftchev{transform:rotate(-45deg)}

.mockroot .driftrules{list-style:none;margin:12px 0 0;padding:0;
  border-left:2px solid var(--line-strong);padding-left:14px}
.mockroot .driftrules li + li{border-top:1px solid var(--line-soft)}
.mockroot .driftrules a{display:flex;align-items:baseline;gap:10px;padding:7px 0;
  font-size:14px;line-height:1.45;color:var(--ink);text-decoration:none}
.mockroot .driftrules a:hover{color:var(--beam)}
.mockroot .driftrules a:focus-visible{outline:2px solid var(--beam);outline-offset:2px}
/* The locator — "page 34". Opaque to us, and the only thing on the row that
   tells somebody where to go and look. */
.mockroot .driftrules b{margin-left:auto;font-family:var(--mono);font-size:10.5px;
  font-weight:400;color:var(--ink-4);white-space:nowrap}

@media (max-width:640px){
  .mockroot .driftgroup{flex-wrap:wrap;gap:8px}
  .mockroot .driftcount{margin-left:0}
  .mockroot .driftrules b{margin-left:0}
  .mockroot .driftrules a{flex-wrap:wrap;gap:4px}
}

@media (prefers-reduced-motion:reduce){
  .mockroot .driftchev,.mockroot .driftgroup{transition:none}
}


/* =========================================================================
 * SORTABLE COLUMNS — see `design/columns.tsx`
 *
 * A header that sorts has to look like a control at rest. The whole of it is
 * the button, so the target is the word plus its mark rather than a five-pixel
 * arrow beside a label, and the mark on the ACTIVE column is drawn at full
 * strength permanently — hover does not exist on a phone and is not a way to
 * find something on a mouse either. The inactive columns carry the same shape
 * at a quarter opacity, which is what says "these sort too" without turning
 * the header row into a row of arrows.
 * ========================================================================= */
.mockroot .colscroll{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface)}
.mockroot .colscroll:focus-visible{outline:2px solid var(--beam);outline-offset:2px}

.mockroot .colsort{display:inline-flex;align-items:center;gap:7px;padding:0;border:0;
  background:transparent;font:inherit;letter-spacing:inherit;text-transform:inherit;
  color:inherit;cursor:pointer;border-radius:3px;transition:color .12s}
.mockroot .colsort:hover{color:var(--ink-2)}
.mockroot .colsort.on{color:var(--ink)}
.mockroot .colsort:focus-visible{outline:2px solid var(--beam);outline-offset:3px}

/* Drawn with borders rather than a glyph: a header row repeats this five times
   and a sprite lookup per column is a sprite lookup for a triangle. */
.mockroot .colmark{width:0;height:0;flex:none;
  border-left:4px solid transparent;border-right:4px solid transparent}
.mockroot .colmark.asc{border-bottom:5px solid currentColor}
.mockroot .colmark.desc{border-top:5px solid currentColor}
.mockroot .colmark.off{border-bottom:5px solid currentColor;opacity:.22}
.mockroot .colsort:hover .colmark.off{opacity:.5}


/* =========================================================================
 * THE REGISTER, AS A TABLE
 *
 * Five columns of a wide one — the object as it was named runs to a full
 * sentence of regulated wording, and the reason beneath it to two. So the
 * table has a floor of 940px and scrolls inside `.colscroll`; the page must
 * never scroll sideways, because that moves the heading that says which screen
 * this is.
 *
 * The rail down the first cell is the tell the cards carried on their left
 * edge: solid for an entry a person made, dashed for one the platform made on
 * its own. The Who column says the same thing in words — the rail is what
 * makes it answerable at a glance down four hundred rows.
 * ========================================================================= */
.mockroot table.regtable{min-width:940px;margin:0;font-size:13.5px}
.mockroot .regtable th{padding:11px 14px;border-bottom:1px solid var(--line);
  white-space:nowrap;vertical-align:bottom}
.mockroot .regtable td{padding:11px 14px;border-bottom:1px solid var(--line-soft);
  vertical-align:top;color:var(--ink-2)}
.mockroot .regtable tbody tr:last-child td{border-bottom:none}
.mockroot .regtable tbody tr:hover{background:var(--surface-2)}

.mockroot .regtable td.cwhen{border-left:3px solid var(--ink-3);
  font-family:var(--sans);font-size:11px;font-variant-numeric:tabular-nums;
  color:var(--ink-3);white-space:nowrap}
.mockroot .regtable tr.auto td.cwhen{border-left-style:dashed;border-left-color:var(--line-strong)}

.mockroot .regtable .cact{width:15rem;color:var(--ink);font-weight:600}
.mockroot .regtable .cabout{min-width:26rem;max-width:40rem}
.mockroot .regtable .cwho{width:12rem;white-space:normal}
.mockroot .regtable .cstand{width:13rem}

/* The kind of object, above the object. One noun, quiet, so the sentence
   underneath it is what the eye lands on. */
.mockroot .regkind{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4);margin-bottom:3px}
.mockroot .regsubj{color:var(--ink);line-height:1.5}
/* Serif, because a reason is somebody's own words about a regulated act and is
   quoted in the export exactly as typed. */
.mockroot .regwhy{font-family:var(--serif);font-size:13.5px;line-height:1.5;
  color:var(--ink-2);margin-top:7px;padding-left:11px;border-left:2px solid var(--line-strong)}
/* A div rather than a flex `td`: `display:flex` on a table cell takes it out of
   the table's own layout and the column stops lining up with its header. */
.mockroot .regstand{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.mockroot .regstand .provchip{white-space:normal;text-align:left}
/* Nothing is outstanding on this entry. An em dash, never a blank cell: a
   blank reads as a fact nobody recorded. */
.mockroot .regnil{color:var(--ink-4)}

/* The sort toggle that used to sit in the filter bar is now the When header,
   so the bar is six areas rather than seven. */
.mockroot .filterbar{grid-template-areas:"q q k a f t";
  grid-template-columns:2fr 0 1.1fr 1.3fr .9fr .9fr}
@media (max-width:900px){
  .mockroot .filterbar{grid-template-areas:"q q" "k a" "f t";
    grid-template-columns:1fr 1fr}
}

/* =========================================================================
 * THE ONE DOOR INTO THE BACKOFFICE
 *
 * A single row at the foot of the account index, for the one person in the
 * company who is platform staff. Not a `.navcard`: the cards above are a grid
 * of things belonging to this account, and a seventh tile reading "every other
 * account" would file a cross-tenant surface under the customer's own
 * settings.
 *
 * It is an `<a>` and the whole rectangle is the target. A row with a button on
 * its right edge is two targets for one destination, and the larger of the two
 * is dead.
 * ========================================================================= */
.mockroot a.staffrow{display:flex;flex-wrap:wrap;align-items:flex-start;gap:6px 11px;
  padding:13px 15px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);text-decoration:none;color:var(--ink-2);
  font-size:13px;line-height:1.5;transition:border-color .12s,background .12s}
.mockroot a.staffrow:hover{border-color:var(--line-strong);background:var(--surface-2)}
.mockroot a.staffrow .ico{margin-top:2px;flex:0 0 auto;color:var(--ink-3)}
/* `flex:1 1 0`, not `auto`. A wrapping flex line is broken on each item's BASE
   size, and a base of `auto` on a sentence is its max-content width — so the
   sentence took a line of its own and left the glyph stranded on the one above.
   A zero basis lets it shrink beside the glyph instead, which is the only
   reason the two ever share a line. */
.mockroot a.staffrow .staffwhat{flex:1 1 0;min-width:12rem}
.mockroot a.staffrow b{display:block;color:var(--ink);font-weight:600;font-size:14px}
/* The affordance is the only thing that drops to a second line, and it drops
   under the label rather than being squeezed to a column two characters wide. */
.mockroot a.staffrow .staffgo{margin-left:auto;flex:0 0 auto;font-family:var(--sans);
  font-size:10.5px;color:var(--ink-4)}


/* =========================================================================
 * AN ADVICE PANEL THAT MIXES ROWS THAT GO SOMEWHERE WITH ROWS THAT DO NOT
 *
 * Every line in an advice panel used to be a link, so `:first-of-type` — which
 * matches the first of each ELEMENT type, not the first row — happened to hit
 * exactly the row anybody meant.
 *
 * Signals now draws one line that deliberately has nowhere to go: "the
 * watchlist holds no rulebook for this industry in these markets" is a gap in
 * our own coverage, and a link on it would promise somewhere to fix it. That
 * line is a <div> among <a>s, so `:first-of-type` fired a second time in the
 * middle of the list and quietly removed the separator above it — two rows run
 * together, and the reader reads one suggestion where there are two.
 *
 * So the separator is on every row, and the one directly under the panel's
 * eyebrow is the exception. That is what the rule always meant.
 * ========================================================================= */
.mockroot .advice > .advicerow:first-of-type{border-top:1px solid var(--line-soft);
  padding-top:9px}
.mockroot .advice > .eyebrow + .advicerow{border-top:0;padding-top:4px}

/* =========================================================================
 * WORK: THE TWO CONTROLS, AND THE LINE BETWEEN THEM
 *
 * Work had a view switcher and nothing else, and three of the four views
 * silently swapped the SET as well as the drawing — so a brand with seventeen
 * pieces opened a grid with two in it. The rail now owns which work is on
 * screen and the switcher owns how it is drawn, and this is the row that puts
 * them beside each other while keeping them visibly separate: the campaign
 * picker sits at the natural start of the line and the four drawings are
 * pushed to the far end of it.
 * ========================================================================= */
.mockroot .wtop{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:18px 0 0}
.mockroot .wdraw{display:flex;gap:6px;flex-wrap:wrap;margin-left:auto;min-width:0}
/* At 390px the picker already fills the line, so `auto` would leave the four
   buttons hanging off the right of their own wrapped row. */
@media (max-width:640px){ .mockroot .wdraw{margin-left:0} }

/* What the section is not showing, and where the rest of it is. Every section
   but Everything holds work back, and a screen that filters silently is what
   this one was reported for. */
.mockroot .whiding{font-size:13.5px;line-height:1.55;color:var(--ink-2);
  max-width:72ch;margin:10px 0 0}
.mockroot .whiding a{color:var(--ink-2);text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:var(--line-strong)}
.mockroot .whiding a:hover{color:var(--ink);text-decoration-color:var(--ink-3)}

/* The campaign picker's rows are buttons rather than divs with a role on them,
   so `.found div` no longer reaches them. Same treatment, plus the hover and
   focus a real control has to have. */
.mockroot .found button.foundrow{background:var(--surface);padding:11px 14px;
  display:flex;align-items:center;gap:11px;font-size:13.5px;width:100%;
  border:0;border-radius:0;text-align:left;cursor:pointer;color:var(--ink-2)}
.mockroot .found button.foundrow:hover{background:var(--surface-2)}
.mockroot .found button.foundrow:focus-visible{outline:2px solid var(--beam);outline-offset:-2px}
.mockroot .found button.foundrow[aria-current]{background:var(--surface-3)}

/* Bringing a piece back out of Put away. Two things stacked rather than side
   by side: the date it went away is the fact, the button is the act, and at
   the width this column gets they do not sit on one line. */
.mockroot .wlist td.wlback{white-space:nowrap}
.mockroot .wlback .mono{display:block;font-size:11px;color:var(--ink-4);margin-bottom:6px}


/* =========================================================================
 * THE TOP BAR ON A PHONE
 *
 * `.tabs` is a flex row and `.tab` never said it would not shrink, so at 390px
 * six tabs were squeezed to about 25px each — three pixels of content box
 * inside 22px of padding — and the labels printed straight over one another:
 * "DeskStudWo Rules Signals Record". Not overflow, so no scrollWidth
 * measurement ever caught it, and it was on EVERY signed-in screen.
 *
 * Two rows rather than a scrolling strip. A strip that slides sideways hides
 * whichever tabs are off the edge behind a gesture nobody is told about, and
 * six labels wrap into two rows in less height than a strip plus its own
 * affordance would take.
 *
 * The brand switcher is the other thing that cannot hold its width here: a
 * long client name pushed the tabs into the squeeze in the first place, so it
 * is capped and truncates. Its full value is still the accessible name.
 * ========================================================================= */
@media (max-width:820px){
  .mockroot .topnav{flex-wrap:wrap;gap:10px 14px;padding:10px 14px}
  .mockroot .topnav .left{flex-wrap:wrap;gap:12px;min-width:0;flex:1 1 100%}
  /* Its own line inside `.left`, so the logo keeps the row above it. */
  .mockroot .tabs{flex-wrap:wrap;gap:4px;width:100%;min-width:0}
  /* The fix. A tab is as wide as its label and never narrower. */
  .mockroot .tab{flex:none;font-size:12px;padding:5px 9px}
  .mockroot .switcher{max-width:52vw;min-width:0;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap}
}


/* =========================================================================
 * THE DESK ON A PHONE, AND A CLIENT ROW THAT IS THE CONTROL
 *
 * The 51px of horizontal overflow this screen carried at 390px is gone, and
 * not by anything below: `.wrow2`'s fixed tracks were the whole of it, and the
 * 640px collapse further up this file already removed them. Reinstating that
 * one rule in a browser reproduces 51 to the pixel. The backlog item was stale.
 *
 * What survived every one of those fixes is the sweep panel, because its
 * overflow could not be measured. `.awaycard` carries `overflow:hidden` for its
 * gradient, so 37px of a `.awayitem` running past the card's content box never
 * reached `document.documentElement.scrollWidth` and no phone check in this
 * project could see it. What it did instead was squeeze the call to action:
 * "Look at them" was 81px of un-wrappable uppercase mono in a flex row that
 * gave it 22px, so the one instruction rendered "LOOK AT" and stopped at the
 * card's edge. Clipped, not scrollable — there was no gesture that would have
 * revealed it. The cta is sentence-case sans now, and narrower for it.
 *
 * The fix is a line each. The icon and the finding keep the first, the call to
 * action takes the second and indents under the text rather than under the
 * glyph, so the row still reads as one thing.
 * ========================================================================= */
@media (max-width:640px){
  .mockroot .awayitem{flex-wrap:wrap;gap:4px 11px}
  /* 13px of `.ico.s` plus the row's 11px gap: the second line starts where the
     first line's words do. */
  .mockroot .awayitem .awaytext{flex:1 1 calc(100% - 24px)}
  .mockroot .awayitem .awaycta{flex:1 0 100%;margin-left:0;padding-left:24px}
  .mockroot .awayitem:hover .awaycta{transform:none}
}

/* A client row IS the control.
 *
 * It was a div with an Open button on its right edge — two targets for one act,
 * which is the defect `.advicerow` and `.driftgroup` were both rebuilt to
 * remove, and the one the owner has called out more than once. The row is an
 * anchor now and carries `.advicego`, so it is the same tell in the same accent
 * with the same chevron as every other actionable row in the product, visible
 * at rest rather than only under a pointer.
 *
 * `.crow2`'s own grid, padding and dividers are untouched: this adds what an
 * anchor needs and nothing about how the row is laid out. */
.mockroot a.crow2{text-decoration:none;color:inherit;cursor:pointer;
  transition:background .12s}
.mockroot a.crow2:hover{background:var(--surface-2)}
.mockroot a.crow2:hover .advicego{color:var(--ink)}
.mockroot a.crow2:hover .advicego::after{transform:rotate(45deg) translate(1.5px,-1.5px)}
/* Inset, because the row runs the full width of a bordered panel and an
   outline outside it would be drawn under the panel's own edge. */
.mockroot a.crow2:focus-visible{outline:2px solid var(--beam);outline-offset:-2px}
/* `.who2` is a flex row and the name block inside it was a div. As spans in an
   anchor they need the block behaviour restated, and the name block needs a
   min-width of zero or a long client name pushes the bar off the row. */
.mockroot .crow2 .who2 > span{display:block;min-width:0}
/* The chevron cell holds one short word. Right of the row on a wide screen,
   with the pill, and on a phone it lands beside the pill in the `auto` track
   the 640px rule already gives this row. */
.mockroot .crow2 .advicego{justify-content:flex-end}

@media (prefers-reduced-motion:reduce){
  .mockroot a.crow2{transition:none}
  .mockroot a.crow2:hover .advicego::after{transform:rotate(45deg)}
}


/* =========================================================================
 * THE TWO MAKER SCREENS GET RAILS
 *
 * Studio and the document list were each one column holding three screens'
 * worth of material, and the rail split them. What is below is only what the
 * split needed: nothing here restyles anything that already existed.
 *
 * The rule these obey, because the owner has called it out repeatedly: a row
 * that DOES something is a `<button>` or an `<a>` the full width of the row,
 * and it looks different from a static tile AT REST — a border, a raised
 * surface and a direction glyph — rather than only under a mouse. A phone has
 * no hover, and neither does a keyboard.
 * ========================================================================= */

/* A section's opening sentence. One paragraph, measured, above the controls. */
.mockroot .secsay{font-size:13.5px;line-height:1.6;color:var(--ink-2);
  max-width:74ch;margin:0 0 14px}

/* Two ways onward from a panel, on one line. */
.mockroot .seealls{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:center}
.mockroot .seealls .seeall{margin-top:12px}

/* ---------------------------------------------------------------------------
 * DOCUMENTS IN PROGRESS, ON THE STUDIO
 *
 * These were `<div>`s with the word "open" linked on the right edge: a 30px
 * target on a 700px row, and nothing at rest saying the rest of the row did
 * anything at all.
 * ------------------------------------------------------------------------ */
.mockroot .wdocs{display:grid;gap:8px;margin-top:12px}
.mockroot .wdoc{position:relative;display:flex;flex-direction:column;gap:3px;
  padding:12px 38px 12px 14px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);text-decoration:none;color:inherit;
  transition:border-color .15s,transform .15s}
.mockroot .wdoc::after{content:"→";position:absolute;right:14px;top:50%;
  transform:translateY(-50%);color:var(--ink-4);font-size:14px}
.mockroot .wdoc:hover{border-color:var(--ink-3);transform:translateY(-1px)}
.mockroot .wdoc:hover::after{color:var(--ink-2)}
.mockroot .wdocname{font-size:14px;font-weight:600;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .wdocmeta{font-family:var(--sans);font-size:11px;color:var(--ink-4)}

/* ---------------------------------------------------------------------------
 * WHAT A BRAND LOOKS LIKE
 *
 * Read-only, and drawn as tiles rather than rows for exactly that reason:
 * nothing in here is a target, so nothing in here carries a border, a raised
 * surface or a direction glyph. A swatch that looked like the rows above it
 * would be a control that does nothing, which is worse than no control.
 * ------------------------------------------------------------------------ */
/* The one band head on this screen that carries a CONTROL rather than a count,
   and the reason it needs its own class: `.bandh` is `space-between` and does
   not wrap, so at 390 the button ran off the right edge of the frame with its
   label cut through the middle. Seen on screen. The heading is allowed to
   shrink to 14rem and the button never is, so on a phone the button drops onto
   its own line and spans it — which is where a thumb expects it anyway. */
.mockroot .bandh.kitact{flex-wrap:wrap;gap:10px}
.mockroot .bandh.kitact h4{flex:1 1 14rem;min-width:0}
.mockroot .bandh.kitact .btn{flex:0 0 auto}
@media (max-width:560px){
  .mockroot .bandh.kitact .btn{flex:1 0 100%;justify-content:center}
}

.mockroot .kitpanel{padding:20px;border-radius:var(--r-lg);background:var(--surface-2)}
.mockroot .kitspec{font-size:34px;line-height:1.1;letter-spacing:-.02em;color:var(--ink)}
.mockroot .kitbody{margin-top:10px;font-size:15px;line-height:1.6;color:var(--ink-2);
  max-width:60ch}
.mockroot .kitpanel .tech{display:block;margin-top:12px;color:var(--ink-4)}
.mockroot .kitnone{font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:74ch;
  margin:6px 0 0}

.mockroot .swatches{display:grid;gap:10px;margin-top:10px;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,168px),1fr))}
.mockroot .swatch{display:flex;flex-direction:column;gap:4px;padding:12px;
  border-radius:var(--r);background:var(--surface-2)}
.mockroot .schip{display:block;height:46px;border-radius:var(--r-sm);
  border:1px solid var(--line-strong)}
.mockroot .sname{font-size:13.5px;font-weight:600}
.mockroot .swatch .tech{color:var(--ink-4)}
/* The one swatch the renderer actually paints with. Said in words, because a
   ring around it would be a third meaning for a border on this screen. */
.mockroot .spri{color:var(--ink-2)}
.mockroot .mchip{display:grid;place-items:center;height:46px;border-radius:var(--r-sm);
  border:1px solid var(--line-strong);background:var(--surface)}
.mockroot .mchip.on-dark{background:var(--ink)}
.mockroot .mchip img{max-height:34px;max-width:100%;object-fit:contain}

.mockroot .kitrules{margin:8px 0 0;padding-left:20px;max-width:74ch;
  font-size:13.5px;line-height:1.7;color:var(--ink-2)}

/* ---------------------------------------------------------------------------
 * WHICH KIT A PIECE IS STARTED IN
 *
 * Only drawn when a brand has more than one, so most accounts never see it.
 * Above the format gallery rather than beside it: pressing a format is what
 * makes the piece, so a chooser underneath would arrive after its consequence.
 *
 * The colour is on the chip, not in words. These are looks, and a row of names
 * is a row of things nobody can tell apart until they have made one in each.
 * ------------------------------------------------------------------------ */
.mockroot .kitpick{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px}
.mockroot .kitopt{display:flex;align-items:center;gap:8px;
  padding:7px 12px 7px 8px;border:1px solid var(--line);border-radius:999px;
  background:var(--surface);cursor:pointer;
  transition:border-color .15s,background .15s}
.mockroot .kitopt:hover{border-color:var(--line-strong)}
.mockroot .kitopt.on{border-color:var(--ink);background:var(--surface-2)}
.mockroot .kchip{display:block;width:18px;height:18px;border-radius:999px;
  border:1px solid var(--line-strong)}
.mockroot .kname{font-size:13.5px;font-weight:600;color:var(--ink)}

/* ---------------------------------------------------------------------------
 * THE FOUR WAYS COPY GETS IN
 *
 * One act — this is where the draft already is — that the product had in three
 * different places, two of them only reachable from inside a document that
 * already existed.
 * ------------------------------------------------------------------------ */
.mockroot .ways{display:flex;flex-direction:column;gap:10px;margin-top:4px}
.mockroot .way{position:relative;display:grid;grid-template-columns:auto 1fr;
  gap:3px 13px;align-items:start;width:100%;text-align:left;
  padding:15px 38px 15px 16px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface);cursor:pointer;
  transition:border-color .15s,background .15s}
.mockroot .way::after{content:"→";position:absolute;right:15px;top:16px;
  color:var(--ink-4);font-size:14px}
.mockroot .way[aria-expanded="true"]::after{content:"↓";color:var(--ink-2)}
.mockroot .way:hover:not(:disabled){border-color:var(--ink-3);background:var(--surface-2)}
.mockroot .way:disabled { opacity:1; cursor:not-allowed;
  background:var(--surface-3); border-color:var(--line);
  color:var(--ink-3); box-shadow:none; }
.mockroot .way .ico{grid-row:1 / span 2;width:20px;height:20px;margin-top:2px;
  color:var(--ink-3)}
.mockroot .wayname{font-size:15px;font-weight:600;letter-spacing:-.01em}
.mockroot .way em{font-style:normal;font-size:13.5px;line-height:1.5;color:var(--ink-2);
  max-width:70ch}

/* What the row opened. Attached to it by sitting flush under it in a quieter
   surface, rather than by a connecting line that breaks when the row wraps. */
.mockroot .waypanel{margin-top:-4px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--surface-2)}
.mockroot .waypanel .tech{color:var(--ink-4)}
.mockroot .waypanel textarea.inp{min-height:180px;line-height:1.6;resize:vertical}


/* =========================================================================
 * WORK THAT OUTLIVES A SCREEN — the top-bar widget and the import wizard.
 *
 * Two surfaces, one idea: a long job is not owned by the route that started
 * it. The widget is how you get back to one; the wizard is where it happens.
 *
 * THERE IS NO PROGRESS BAR IN HERE, and its absence is the specification. A
 * bar that fills while a model is thinking is an animation pretending to be a
 * measurement, on a product whose argument is that it does not do that. What
 * moves is a count of finished work, and it moves because work finished.
 * ========================================================================= */

/* --- the widget -------------------------------------------------------- */

/* Capped and shrinkable. The top bar has already had to be rebuilt once to fit
   six tabs at 390px; a widget that can grow without limit would undo it. */
.mockroot .jobw{position:relative;min-width:0;flex:0 1 auto}
.mockroot .jobwbtn{display:flex;align-items:center;gap:8px;max-width:260px;min-width:0;
  padding:6px 10px;border:1px solid var(--line);border-radius:999px;background:var(--surface-2);
  color:var(--ink-2);font:inherit;font-size:12px;cursor:pointer;text-align:left}
.mockroot .jobwbtn:hover{border-color:var(--line-strong);color:var(--ink)}
.mockroot .jobwbtn:focus-visible{outline:2px solid var(--beam);outline-offset:2px}
.mockroot .jobwn{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.mockroot .jobwn b{font-size:12px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .jobwn span{font-size:11px;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .jobwt{font-size:11px;color:var(--ink-4);flex:none;font-variant-numeric:tabular-nums}

/* The one moving thing in the product, and it moves only while work is
   actually in flight. `.spin` in this sheet is a static ring — this is the
   turning version, kept separate so nothing else starts rotating. */
.mockroot .jobspin{width:12px;height:12px;border-radius:50%;flex:none;
  border:1.5px solid var(--line-strong);border-top-color:var(--beam);
  animation:jobturn .9s linear infinite}
@keyframes jobturn{to{transform:rotate(360deg)}}
.mockroot .jobdot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--cleared)}
.mockroot .jobdot.bad{background:var(--flag)}

.mockroot .jobwpanel{position:absolute;top:calc(100% + 6px);right:0;z-index:60;width:340px;
  max-width:min(340px,90vw);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-3);padding:8px}
.mockroot .jobwrow{display:flex;align-items:center;gap:8px;padding:4px}
.mockroot .jobwgo{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;
  padding:7px 9px;border:0;border-radius:var(--r);background:transparent;
  font:inherit;text-align:left;color:inherit;cursor:pointer}
.mockroot .jobwgo:hover{background:var(--surface-2)}
.mockroot .jobwgo:focus-visible{outline:2px solid var(--beam);outline-offset:-2px}
.mockroot .jobwln{font-size:13px;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .jobwls{font-size:11px;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .jobwcode{font-size:10.5px;color:var(--ink-4);letter-spacing:.06em}
.mockroot .jobwnote{margin:6px 4px 2px;font-size:11px;line-height:1.5;color:var(--ink-4)}

/* On a phone the bar is already two rows. The widget keeps the spinner and the
   elapsed figure — the two facts worth the width — and drops the label, which
   is the thing the panel exists to show in full. */
@media (max-width:820px){
  /* The name and the spinner, and nothing else. The elapsed figure sits
     outside the button's max-width because it must not be squeezed, which at
     390px pushed it into the brand switcher beside it — so on a phone it lives
     in the panel, where there is room for it, and the bar keeps the two facts
     that fit: that something is running, and which document it is. */
  .mockroot .jobwbtn{max-width:34vw;padding:5px 8px}
  /* Anchored to the widget's LEFT edge here, not its right. The bar wraps at
     this width and the widget ends up at the start of its row, so a panel
     hanging off the right edge of a 200px button ran 160px off the side of the
     screen and took the file name with it. */
  .mockroot .jobwpanel{left:0;right:auto}
  .mockroot .jobwn b{font-size:11px}
  .mockroot .jobwn span{display:none}
  .mockroot .jobwbtn .jobwt{display:none}
}

/* --- the wizard -------------------------------------------------------- */

/* `margin:auto` is what centres a <dialog> opened with showModal(), and it
   comes from the user-agent stylesheet — which Tailwind's preflight zeroes
   along with every other margin. Without it the dialog sits in the top-left
   corner, which is where the owner found it. */
.mockroot .impw{box-sizing:border-box;margin:auto;width:min(720px,94vw);max-height:88vh;padding:0;border:1px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface);color:var(--ink);
  box-shadow:var(--shadow-3);overflow:hidden}
.mockroot .impw::backdrop{background:color-mix(in srgb,#000 55%,transparent)}
.mockroot .impwhead{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:17px 20px 14px;border-bottom:1px solid var(--line)}
/* The close control never shrinks and never wraps — it is the way out of a
   modal, and a way out that is half off its own dialog is not one. The title
   beside it is what gives, because a title can wrap. */
.mockroot .impwhead > .btn{flex:none;white-space:nowrap}
.mockroot .impwhead h2{margin:3px 0 0;font-size:20px;font-weight:600;letter-spacing:-.02em}
.mockroot .impwbody{padding:16px 20px 22px;overflow-y:auto;max-height:calc(88vh - 74px)}
.mockroot .impwlede{margin:0 0 16px;font-size:13.5px;line-height:1.6;color:var(--ink-2);max-width:64ch}
.mockroot .impwnote{margin:12px 0 0;font-size:12px;line-height:1.6;color:var(--ink-3);max-width:66ch}
.mockroot .impwbad{margin:9px 0 0;font-size:12px;line-height:1.6;color:var(--flag)}

/* The two ways in, given equal weight. Whichever one somebody has is the one
   they will use, and ranking them would slow down half the people arriving. */
.mockroot .impwways{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(248px,1fr))}
.mockroot .impwway{display:flex;flex-direction:column;padding:15px 16px;border:1px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface-2);min-width:0}
.mockroot label.impwway{cursor:pointer}
.mockroot label.impwway:hover{border-color:var(--line-strong)}
.mockroot .impwwayt{font-size:14px;font-weight:600}
.mockroot .impwwayd{margin-top:4px;font-size:12px;line-height:1.55;color:var(--ink-3)}

/* The steps. A name, a real count where there is one, and a measured time. */
.mockroot .impwsteps{margin:2px 0 16px;border:1px solid var(--line);border-radius:var(--r-lg);
  padding:6px 14px 12px;background:var(--surface-2)}
.mockroot .impwstep{display:flex;align-items:center;gap:10px;padding:9px 0;
  border-bottom:1px solid var(--line-soft)}
.mockroot .impwstep:last-of-type{border-bottom:0}
.mockroot .impwstep.waiting{opacity:.45}
.mockroot .impwstepn{flex:1;min-width:0;font-size:13px;color:var(--ink-2)}
.mockroot .impwstep.running .impwstepn{color:var(--ink)}
.mockroot .impwstepn b{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.mockroot .impwstept{font-size:11px;color:var(--ink-4);font-variant-numeric:tabular-nums}

/* --- what came out of their file --------------------------------------- */

/* The arrival moment. Before anything is asked of them, they are shown what
   was actually found in the document they just handed over. */
.mockroot .docrx{margin:4px 0 0;border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--surface-2);padding:15px 17px}
.mockroot .docrxh{display:flex;align-items:center;gap:9px;min-width:0}
.mockroot .docrxn{flex:1;min-width:0;font-size:15px;font-weight:600;letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mockroot .docrxf{display:flex;flex-wrap:wrap;gap:22px;margin-top:13px}
.mockroot .docrxf b{display:block;font-family:var(--sans);font-size:20px;letter-spacing:-.02em}
.mockroot .docrxf span{display:block;margin-top:2px;font-size:11px;color:var(--ink-3)}
.mockroot .docrxnote{margin:11px 0 0;font-size:12px;line-height:1.6;color:var(--ink-3);max-width:66ch}
.mockroot .docrxtext{margin-top:12px}
.mockroot .docrxtext summary{cursor:pointer;font-size:12px;color:var(--ink-3)}
.mockroot .docrxtext summary:hover{color:var(--ink-2)}
.mockroot .docrxtext pre{margin-top:9px;max-height:15rem;overflow:auto;white-space:pre-wrap;
  font-size:12px;line-height:1.5;color:var(--ink-3);background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);padding:10px 12px}

/* --- what it found ------------------------------------------------------ */

.mockroot .impwfound{margin-top:18px}

/* Nine proposed, three traced. The most trust-building line on the screen, so
   it sits above the findings rather than under them. */
.mockroot .tracebar{display:flex;flex-wrap:wrap;gap:14px 26px;padding:13px 16px;
  border:1px solid var(--line);border-left:3px solid var(--cleared);
  border-radius:var(--r-lg);background:var(--surface-2)}
.mockroot .tracebar > div{min-width:0}
.mockroot .tracebar b{display:block;font-family:var(--sans);font-size:24px;letter-spacing:-.02em}
.mockroot .tracebar span{display:block;margin-top:2px;font-size:11px;color:var(--ink-3);max-width:34ch}
.mockroot .tracebar .traceout b{color:var(--ink-3)}
.mockroot .tracebar p{flex:1 1 100%;margin:0;font-size:12px;line-height:1.6;color:var(--ink-3);
  max-width:70ch}

.mockroot .finding{margin-top:14px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface)}

/* Theirs and ours, side by side, with the evidence under both — because the
   evidence belongs to both: the tightened rule is the same sentence reworded,
   not a different finding. */
.mockroot .twoup{display:grid;gap:10px;margin-top:9px;
  grid-template-columns:repeat(auto-fit,minmax(232px,1fr))}
.mockroot .twoup.one{grid-template-columns:1fr}
.mockroot .ver{display:flex;flex-direction:column;gap:6px;padding:11px 13px;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--r);background:var(--surface-2);min-width:0}
.mockroot .ver:hover{border-color:var(--line-strong)}
.mockroot .ver.on{border-color:var(--beam);background:var(--surface)}
.mockroot .ver:focus-within{outline:2px solid var(--beam);outline-offset:2px}
.mockroot .verh{display:flex;align-items:center;gap:8px}
.mockroot .vert{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-3)}
.mockroot .ver.on .vert{color:var(--ink-2)}
.mockroot .vert em{font-style:normal;color:var(--ink-4)}
.mockroot .verS{font-size:13.5px;line-height:1.55;color:var(--ink)}
.mockroot .findingq{margin-top:11px}
.mockroot .findingok{margin:9px 0 0;font-size:12px;line-height:1.55;color:var(--ink-4)}

/* --- the receipt -------------------------------------------------------- */

/* A code is not a headline. Small, quiet, monospace and selectable: ignorable
   by somebody who will never report it, copyable in one gesture by somebody
   who will. */
.mockroot .failcode{margin-left:9px;font-size:10.5px;letter-spacing:.08em;color:var(--ink-4);
  user-select:all;font-weight:400;text-transform:none}

/* Nothing here moves for anybody who asked for less movement. The spinner
   becomes a mark that is present rather than a mark that turns — the state is
   still readable, which is the part that mattered. */
@media (prefers-reduced-motion:reduce){
  .mockroot .jobspin{animation:none;border-top-color:var(--beam);border-right-color:var(--beam)}
}

@media (max-width:640px){
  .mockroot .impwhead{padding:14px 15px 12px}
  .mockroot .impwbody{padding:14px 15px 20px}
  .mockroot .tracebar b{font-size:20px}
}


/* =========================================================================
 * WHOSE PIECE IT IS
 *
 * The desk drew a face and a date in this cell on every row, and the face was
 * whoever was holding the piece — which on your own desk is your own picture,
 * telling you nothing, and on a colleague's piece was a portrait with no
 * sentence saying what it meant. Now the two lanes say different things in the
 * same cell: words on your lane, a name beside the face on the other.
 *
 * `min-width:0` and the truncation are not decoration. `Dr Ingrid
 * Sørensen-Whitlock` is 27 characters in a 118px track, and unbounded it takes
 * the width from the title column that the row exists to show.
 * ========================================================================= */
.mockroot .deskwho{display:flex;align-items:center;gap:8px;min-width:0;
  font-size:12px;color:var(--ink-3);line-height:1.35}
/* The name and the date are a column, and the clamp is on the NAME ALONE.
   Clamped together, a two-line name pushed the date off the row — so the lane
   that exists to say who has a piece quietly stopped saying how long they had
   had it, which is the half of it that tells you whether it is stuck. */
.mockroot .deskwhocol{min-width:0}
/* Two lines and then an ellipsis, never one line and then an ellipsis.
   "Dr Ingrid Sor..." is the one truncation this screen cannot afford, and the
   full value is on `title` besides, because a clamp is still a clamp. */
.mockroot .deskwhon{display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden;min-width:0}
/* The elapsed time, under the name rather than beside it: it is the second
   thing you want and it must never be what pushes the first one out. */
.mockroot .deskwhen{display:block;color:var(--ink-4);
  font-family:var(--sans);font-size:10.5px}
/* Wider meta track on the lane that carries a person. Above the phone
   breakpoint only — below it the row is already two columns and this would put
   a fixed track back into a layout that was fixed by removing them. */
@media (min-width:641px){
  .mockroot .wrow2.named{grid-template-columns:56px 1fr 112px 152px auto}
}


/* The two studio panels stop being forced to the same height.
 *
 * `.studios` is a grid, so both cells stretched to the taller of the two — and
 * once the four most-recent documents moved out of the Copy panel and into the
 * In progress section, that left a 350px column of empty gradient beside the
 * format gallery. A panel should be as tall as what is in it. */
.mockroot .studios{align-items:start}

/* TWO OF THE SIX FORMAT HUES WERE ORANGE.
 *
 * `#E0603A` and `#C2410C` are the terracotta this product does not use — it is
 * the colour every AI-built interface reaches for first, and two of the six
 * cards in the gallery were wearing it. Replaced rather than removed, because
 * the six hues are doing identification: grey on grey made a gallery of six
 * cards nobody could tell apart, which is the thing they fixed.
 *
 * Crimson and olive are both already in this product's vocabulary — they are
 * two of the six `AV_HUES` the avatars use — and both stay distinguishable
 * from the blue, green, violet and teal they sit beside. */
.mockroot .tmplgrid .tmpl:nth-child(6n+3){ --tmpl-a:#B3245C }
.mockroot .tmplgrid .tmpl:nth-child(6n+5){ --tmpl-a:#5B7A2E }


/* =========================================================================
 * ACCEPT AND MODIFY
 *
 * The import wizard offered two fixed wordings and no text field anywhere, so
 * a rule that was one character wrong could only be thrown away. This is the
 * third version — theirs — and everything here is about keeping one distinction
 * visible while somebody types: the rule is theirs to word, and the quote under
 * it is the document's and is not a control.
 *
 * The panel is INSIDE the finding and set on the raised surface, so it reads as
 * part of the thing being edited rather than as a form that has opened over it.
 * ========================================================================= */

.mockroot .edpanel{margin-top:12px;padding:13px 14px;border:1px solid var(--line-strong);
  border-radius:var(--r);background:var(--surface-2)}
.mockroot .edhead{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;
  margin-bottom:11px;min-width:0}
/* Where the fields were filled from, and what an edit cannot reach. Said once,
   at the top, rather than repeated beside every field. */
.mockroot .edfrom{flex:1 1 20ch;min-width:0;font-size:12px;line-height:1.55;color:var(--ink-3)}

.mockroot .edfield{margin-top:11px;min-width:0}
.mockroot .edfield:first-of-type{margin-top:0}
.mockroot .edlab{display:block;font-size:13px;font-weight:600;color:var(--ink)}
.mockroot .edhelp{display:block;margin-top:2px;font-size:12px;line-height:1.5;color:var(--ink-3);
  max-width:60ch}
/* Tighter than the arrival form's `.inp`: this is a field beside a quote in a
   list of forty findings, not the one thing on the screen. */
.mockroot .edinp{margin-top:6px;padding:8px 11px;font-size:13.5px;background:var(--surface)}
.mockroot textarea.edblock{line-height:1.55;resize:vertical;min-height:62px;
  font-family:inherit}
.mockroot select.edinp{cursor:pointer}

/* The live answer, per field, as a sentence. Never a border on its own: a
   border can say something is wrong and cannot say that the rule is still
   perfectly allowed and simply no longer a quotation. */
.mockroot .edfound,.mockroot .edaway{margin:5px 0 0;font-size:12px;line-height:1.5;max-width:62ch}
.mockroot .edfound{color:var(--cleared)}
.mockroot .edaway{color:var(--flag)}

/* THE MOMENT THE RULE STOPS BEING A QUOTATION.
 *
 * In the judgement colour, not the refusal colour. This is not a mistake being
 * blocked — somebody who knows their own brand book is frequently right where
 * the extractor was clumsy. It is a decision being named, which is the same
 * thing `--judge` marks everywhere else in this product. */
.mockroot .edcross{margin-top:12px;padding:10px 12px;border:1px solid var(--judge);
  border-left-width:3px;border-radius:var(--r-sm);background:var(--judge-wash)}
.mockroot .edcross .vert{display:block;color:var(--judge)}
.mockroot .edcross p{margin:4px 0 0;font-size:12px;line-height:1.6;color:var(--ink-2);max-width:66ch}

/* And said again with the editor shut, next to the button that commits it —
   because that is where the decision is actually taken. */
.mockroot .findingmine{margin:10px 0 0;padding-left:11px;border-left:3px solid var(--judge);
  font-size:12px;line-height:1.6;color:var(--ink-2);max-width:70ch}
.mockroot .findingmine b{font-weight:600;color:var(--ink)}

/* `.twoup` is left alone with three cards in it. `auto-fit` at minmax(232px)
   wraps the third onto its own row rather than squeezing three columns into
   540px, which is the behaviour wanted and needed no new rule — MEASURED at
   390, 720 and 1512. */


/* =========================================================================
 * TYPE THAT IS UNDER THE SCALE'S OWN FLOOR
 * =========================================================================
 *
 * The token repair above makes `--ink-4` legible. It does not make 9px
 * legible, and 30 rules in this file set `--ink-4` at 9, 9.5 or 10px.
 *
 * `src/ui/scale.test.ts` allows 10.5 as the smallest step in the product and
 * says why: 11 was tuned for sentence case, and 10.5 was the step under it a
 * tracked uppercase label could hold. There is no step below it. That test
 * only reads `text-[Npx]` in TSX, so it has never been able to see this
 * stylesheet, and this stylesheet has been running five sizes — 6.5, 8.5, 9,
 * 9.5 and 10 — that the product forbids.
 *
 * Contrast and size were one problem here rather than two. A 9px uppercase
 * mono label at 0.09em tracking had perhaps half the stem area of 13px sans,
 * so the same ratio bought less of the legibility it is a proxy for. These
 * labels are sentence-case sans now — mono is for identifiers alone — which
 * recovers the stem area at every one of these sizes. The sizes stand: they
 * were the floor, and the floor was never a compensation for the family.
 *
 * Three treatments, because there are three different jobs being done.
 *
 * 1. METADATA, to 10.5 — the floor. Source lines, counts, dates, section
 *    eyebrows: real text, read once, correctly quiet.
 *
 * 2. CONTENT AND CONTROLS, to 11. A column header is how the table is read at
 *    all; a call to action is a control; an explanation is a sentence. None of
 *    these were ever metadata and they should not have been at the floor, let
 *    alone under it.
 *
 * 3. THE MINIATURE, left exactly as it is. `.pdfprev` is a 230px scale drawing
 *    of the PDF the Record exports — 6px serif and 6.5px mono because it is a
 *    picture of a page, not text anybody reads. Enlarging its type would stop
 *    it looking like a document, which is its whole job. A drawing is not made
 *    accessible by making it bigger; it is made accessible by not being
 *    announced as text, so `Record.tsx` marks it `aria-hidden` and the same
 *    facts are in the rules list beside it.
 *
 * Appended rather than edited in place, per this file's own convention: the
 * lifted artifact stays readable as what it was and the override is legible as
 * a decision. Every selector below is prefixed to match or beat the rule it
 * overrides — see the note on the token block above for what happens when an
 * appended override is less specific than its target.
 * ========================================================================= */

/* 1. Metadata, to the floor. */
.mockroot .eyebrow,
.mockroot .srcline,
.mockroot .found .fsrc,
.mockroot .find .src,
.mockroot .wrow2 .sub2,
.mockroot .bh2,
.mockroot .cell .cm2,
.mockroot .dgrid .k,
.mockroot .figure .fo,
.mockroot .tmplwhere,
.mockroot .firstmeta,
.mockroot .wipmeta,
.mockroot .field label,
.mockroot .awaymeta { font-size:10.5px }

/* 2. Things that were never metadata.
 *
 * `th` is the one that costs the most. A column header at 9.5px is the label
 * every cell under it is read through, set smaller than the data it governs —
 * the hierarchy upside down, on every table in the product. */
.mockroot th { font-size:11px }

/* An explanation and a worked example are sentences. `.advicewhy` is the
   answer to "why is this being suggested", which is the whole reason the
   advice is trusted or dismissed. */
.mockroot .advicewhy,
.mockroot .precex { font-size:11px }

/* Controls. `.awaycta` and `.ncgo` are the affordance on a card — the words
   that say the card goes somewhere — and `summary` is a disclosure button. */
.mockroot .awayitem .awaycta,
.mockroot .navcard .ncgo,
.mockroot .firstmore summary { font-size:11px }

/* The rail's aside was 8.5px, which is smaller than anything else in the
   product by a clear margin and sits in the persistent navigation. */
.mockroot .raillink em { font-size:10.5px }


/* =========================================================================
 * THE COUNT ON THE THUMBNAIL
 * =========================================================================
 *
 * `.fb2` is the badge on a deck's 50×64px thumbnail — open blocking findings
 * on the desk, frames in the studio. It was `#fff` on `--flag-bright`, which
 * is 2.89:1 in dark and the only text-contrast failure left on the desk after
 * the token repair above. A count nobody can read is not a count.
 *
 * A LITERAL, NOT `var(--ink)`. `--ink` flips with the theme — it is #17151C in
 * light and #F0EEF4 in dark — so binding to it would have fixed light and left
 * dark at near-white on pink, which is the failure it was meant to repair. The
 * badge keeps one colour in both themes because the pink underneath it is a
 * mark rather than a surface, and this file already establishes that the marks
 * carry their own colours for exactly this reason.
 *
 *   #17151C on --flag-bright dark  #FF5AA5   6.25:1
 *   #17151C on --flag-bright light #FF2E8E   5.20:1
 *
 * The badge stays small and stays announced. It is a glance marker for a fact
 * the row states in words a few pixels away — "12 STOP RELEASE" — so the
 * reading is never left to 6.5px, but the number still has to be legible to
 * the person glancing at it, which is the whole reason it is drawn.
 * ========================================================================= */
.mockroot .frame .fb2 { color:#17151C }


/* =========================================================================
 * THE PILL SAYS WHETHER SOMETHING CAN SHIP, AT 9.5PX
 * =========================================================================
 *
 * Not an `--ink-4` fault — `.pill` is drawn in `--flag`, `--judge`, `--cleared`
 * and passes contrast on its own wash. It was found by sweeping the rendered
 * desk for text under the scale's floor rather than by grepping for the token,
 * and it is the most consequential string in the product: "12 STOP RELEASE" is
 * the answer to whether a piece of work can be published.
 *
 * It was 9.5px mono, set smaller than the metadata beside it. The floor
 * applies to it more than to anything it sits next to, so it goes to 11 rather
 * than to 10.5 — the same step the column headers took above. It is in sans
 * because a verdict is a state word, and mono here is for identifiers.
 *
 * The padding is unchanged. `.pill` is `inline-flex` with a 999px radius, so
 * the capsule grows with its own text and nothing around it is positioned off
 * its height — MEASURED on the desk, the review queue and the board, which are
 * the three screens that draw it in a fixed-height row.
 * ========================================================================= */
.mockroot .pill { font-size:11px }


/* =========================================================================
 * TWO MORE THE TOKEN GREP COULD NOT HAVE FOUND
 * =========================================================================
 *
 * Both drawn in `--ink-3`, both passing contrast, both far under the floor.
 * They turned up only because the rendered pages were swept for size as well
 * as for tone — which is the argument for the sweep being in the test file
 * rather than being something somebody remembers to do.
 *
 * `.provchip` at 9.5px is provenance in the register and the rule list:
 * "approved by …", "reworded here — the source no longer states this". That is
 * the sentence that says whether a rule is still the source's or has become
 * the customer's own, printed smaller than everything around it. It is a
 * statement, so 11 rather than the 10.5 floor.
 *
 * `.tmplroles em` at 8.5px was the smallest type in the signed-in product
 * outside a miniature — "On the artwork", "Caption", "Image descriptions" —
 * the list of what a template actually writes, which is the one thing that
 * distinguishes one template from another at the moment somebody picks one.
 * ========================================================================= */
.mockroot .provchip { font-size:11px }
.mockroot .tmplroles em { font-size:10.5px }


/* =========================================================================
 * WHAT IS DELIBERATELY LEFT UNDER THE FLOOR
 * =========================================================================
 *
 * Three things, all of them monograms or miniatures rather than text, all
 * verified as carrying their meaning somewhere legible on the same screen:
 *
 *   .av / .av.sm    9.5–11.5px   Initials in a 26px circle. The full name is
 *                                the element's `title`, and the top bar's own
 *                                avatar carries `aria-label`. Enlarging the
 *                                letters means enlarging the circle, which is
 *                                a layout change in the masthead and the team
 *                                stack, not a legibility fix.
 *   .frame .ft2     6.5px        The headline drawn on a 50×64px thumbnail.
 *                                `aria-hidden`; the deck's name is beside it.
 *   .pdfprev *      6–7px        A scale drawing of the exported PDF.
 *                                `aria-hidden`; the rules are listed beside it.
 *
 * Written down because the next person to run a scanner will find them, and
 * the useful thing to hand them is the reasoning rather than a silent
 * exception they have to reconstruct.
 * ========================================================================= */


/* =========================================================================
 * WHAT A DOCUMENT TURNED OUT TO HOLD — see `app/importWizard.tsx`
 *
 * The owner's own brand bible produced 54 findings in extraction order, 51 of
 * them carrying the identical sentence "already precise enough to apply as it
 * stands", four in a row quoting the same table cell. 16,083px of dialog with
 * no answer on it to "what is in my document".
 *
 * Everything below exists to make three things true at a glance: what kinds of
 * rule came out and how many of each, which of their sentences each rule came
 * from, and which few rules have a decision in them.
 * ========================================================================= */

/* The scorecard. Sits directly under the trace count, because "54 traced" and
   "36 of them are words you can't use" are one answer in two halves. */
.mockroot .ishape{margin-top:12px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface-2)}
.mockroot .ishape h3{margin:0 0 11px;font-family:var(--sans);font-size:10.5px;
  font-weight:400;color:var(--ink-3)}
.mockroot .ishapek{display:flex;flex-wrap:wrap;gap:8px}
/* A count that is the only way into the pile it counts has to look like a
   control at rest — hence a border and a hover, not a figure with a link
   hiding in it. */
.mockroot .ishapei{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 9rem;
  padding:9px 12px;text-align:left;cursor:pointer;font:inherit;color:inherit;
  border:1px solid var(--line);border-radius:var(--r);background:var(--surface)}
.mockroot .ishapei:hover{border-color:var(--beam)}
.mockroot .ishapei:focus-visible{outline:2px solid var(--beam);outline-offset:2px}
.mockroot .ishapei b{font-family:var(--sans);font-size:20px;letter-spacing:-.02em;color:var(--ink)}
.mockroot .ishapei span{font-size:11px;line-height:1.4;color:var(--ink-3)}
.mockroot .ishapen{margin:11px 0 0;font-size:12px;line-height:1.6;color:var(--ink-3);max-width:70ch}
/* Beside the button that would write 54 rules, not under it. */
.mockroot .ishapehint{align-self:center;font-size:12px;color:var(--ink-4)}

/* --- one pile ----------------------------------------------------------- */

.mockroot .ipile{margin-top:10px;border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--surface);overflow:hidden}
.mockroot .ipileh{display:flex;align-items:center;gap:10px;padding:0 14px 0 0}
/* The heading IS the disclosure. Taking the pile is the button beside it —
   a heading that writes 36 rules on one click is one somebody hits by accident. */
.mockroot .ipileb{flex:1;min-width:0;display:flex;align-items:center;gap:10px;
  padding:13px 14px;border:0;background:transparent;font:inherit;color:inherit;
  text-align:left;cursor:pointer}
.mockroot .ipileb:hover .ipilen{color:var(--beam)}
.mockroot .ipileb:focus-visible{outline:2px solid var(--beam);outline-offset:-2px}
.mockroot .ipilen{font-size:15px;font-weight:600;letter-spacing:-.01em;min-width:0}
.mockroot .ipilec{margin-left:auto;font-family:var(--sans);font-size:11px;color:var(--ink-4);
  white-space:nowrap}
.mockroot .ipilechev{width:6px;height:6px;flex:none;border-top:1.5px solid var(--ink-3);
  border-right:1.5px solid var(--ink-3);transform:rotate(135deg);transition:transform .12s}
.mockroot .ipileb[aria-expanded="true"] .ipilechev{transform:rotate(-45deg)}
.mockroot .ipileq{padding:0 14px 14px}

/* --- one quoted sentence, and the rules read out of it ------------------ */

.mockroot .iev{padding-top:13px;border-top:1px solid var(--line-soft)}
.mockroot .ievh{font-family:var(--sans);font-size:10.5px;
  color:var(--ink-4)}
.mockroot .ievh b{font-weight:600;color:var(--ink-3)}
.mockroot .iev .findingq{margin-top:7px}
.mockroot .ievr{margin-top:8px}

/* --- one rule ----------------------------------------------------------- */

.mockroot .irule{border-top:1px solid var(--line-soft)}
/* A rule with a wording to choose, or one somebody has opened, is not at rest.
   It gets a surface of its own so the two states are told apart without
   reading either of them. */
.mockroot .irule.open{margin:0 -8px;padding:0 8px;background:var(--surface-2);
  border-radius:var(--r);border-top-color:transparent}
.mockroot .irule:first-child{border-top:0}
.mockroot .iruleh{display:flex;align-items:center;gap:10px}
/* `flex-start` and a grown statement, not `center` and a wrap: with the
   statement as a rigid flex item, a long one dropped to its own line and left
   the chevron sitting alone above it. It shrinks and wraps inside its own box
   now, so every row starts at the same place whatever its length. */
.mockroot .iruleb{flex:1;min-width:0;display:flex;align-items:flex-start;gap:9px;flex-wrap:wrap;
  padding:9px 0;border:0;background:transparent;font:inherit;color:inherit;
  text-align:left;cursor:pointer}
.mockroot .iruleb:disabled{cursor:default}
.mockroot .iruleb:hover .irules{color:var(--beam)}
.mockroot .iruleb:focus-visible{outline:2px solid var(--beam);outline-offset:2px}
.mockroot .irules{flex:1 1 14rem;font-size:13.5px;line-height:1.5;color:var(--ink);min-width:0}
/* The phrase the sweep runs, and the only thing telling four rules out of one
   table cell apart. Mono because it is a literal string being matched, not
   prose — the same reason a locator is mono everywhere else here. */
.mockroot .irulelede{flex:0 1 auto;font-family:var(--mono);font-size:12px;line-height:1.7;
  color:var(--ink-2);overflow-wrap:anywhere}
.mockroot .irulechev{width:5px;height:5px;margin-top:7px;flex:none;
  border-top:1.5px solid var(--ink-4);border-right:1.5px solid var(--ink-4);
  transform:rotate(135deg);transition:transform .12s}
.mockroot .iruleb[aria-expanded="true"] .irulechev{transform:rotate(-45deg)}
.mockroot .irulea{flex:none}
/* Rare on purpose. A mark on every row is a column, and a column of identical
   words is what this screen already had 51 of. */
.mockroot .irulemark{flex:none;margin-top:3px;font-family:var(--sans);font-size:10.5px;
  color:var(--judge);white-space:nowrap}
/* Attached to the row above it, indented past the chevron, so it reads as a
   remark about that rule rather than as a line between two of them. */
.mockroot .irulesame{margin:-4px 0 8px;padding-left:14px;font-size:12px;line-height:1.5;
  color:var(--ink-4)}
.mockroot .irule .twoup{margin:2px 0 10px}
.mockroot .iruled{padding:0 0 11px}
.mockroot .irulectx{margin:0;font-size:12px;line-height:1.6;color:var(--ink-3);max-width:70ch}

@media (max-width:640px){
  .mockroot .ishapei{flex:1 1 100%}
  /* The count wraps rather than being cut off. "36, from 20 of your sentences"
     is the sentence that explains why the list is shorter than the total, and
     an ellipsis through the middle of it explains nothing. */
  .mockroot .ipileb{flex-wrap:wrap}
  .mockroot .ipilec{margin-left:0;flex:1 1 100%;white-space:normal}
  .mockroot .ipileq{padding:0 10px 12px}
  .mockroot .iruleh{align-items:flex-start;flex-wrap:wrap}
  .mockroot .irulea{padding:0 0 9px}
}

@media (prefers-reduced-motion:reduce){
  .mockroot .ipilechev,.mockroot .irulechev{transition:none}
}
/*
 * THE DESIGN-SYSTEM CATALOGUE'S STYLESHEET.
 *
 * Source: `docs/superpowers/mockups/ds.css`, copied 20 Aug 2026.
 * Generator: `docs/superpowers/mockups/ds.py`, which splices
 * `src/design/mock.css`, then `ds-page.css`, then this file into one <style>
 * block. `Shell.tsx` imports mock.css and then this one; `ds-page.css` is the
 * catalogue page's own furniture and the app does not import it.
 *
 * ---------------------------------------------------------------------------
 * A COPY, BYTE FOR BYTE, AND THIS HEADER IS THE ONLY ADDITION
 * ---------------------------------------------------------------------------
 *
 * `mock.css`'s header records what happened the four times somebody wrote code
 * to decide which rules of a mock were worth keeping: a parser that read
 * `/* platform additions *\/ .topnav` as one selector and dropped twenty-two
 * rules, and a hand-written drop list that threw away `.wrap`. The same
 * decision is available here and it is declined for the same reason. Every
 * rule below is in the file the catalogue page was photographed from, in the
 * order it appears there.
 *
 * If a rule here is wrong, it is wrong in the generator. Fix it there and copy
 * the file again. Editing this one to make a screen look right is the move
 * that produced five failed rollouts, and `calm.css`'s header names it.
 *
 * ---------------------------------------------------------------------------
 * WHAT ROUND ONE CHANGED, IN THE GENERATOR
 * ---------------------------------------------------------------------------
 *
 * The first copy of this file carried the catalogue page's furniture into the
 * app, because the furniture was in `ds.css`. Measured on
 * `/app/account/brands`: `html,body{background:#211f29;font-family:'Avenir
 * Next'}` moved `body` from rgb(14,13,18) to rgb(33,31,41) and its face from
 * Archivo to Avenir Next on every signed-in screen, and an unlayered `.ico`
 * beat `mock.css`'s own `.ico.s`, drawing every 13px icon at 16px. Four things
 * were fixed in `ds.py`/`ds.css`, not here:
 *
 *   - `html,body`, `.ds*` and the base `.ico` moved to `ds-page.css`;
 *   - HERO 4's card is `.covgap`, not `.gap` — the Rules filter row draws
 *     `<i class="c-gut gap">` (`src/design/table.tsx:975`, `calm.css:1979`)
 *     and a 3px gutter tick was taking a 22px/24px padded card;
 *   - `--r-md` and `--thread`, referenced here and defined nowhere, are
 *     declared beside the other tokens;
 *   - five rules naming `.art-f`, `.col h6`, `.lbl`, `.vB-card .m` and `.m` —
 *     the pitch board's, not this page's — are gone from here. `.mockroot .m`
 *     was repainting the Desk's "while you were away" rows.
 *
 * And one more, found by drawing the selection table this round adds: four
 * white marks sat on grounds that turn over with the theme. `.ck.on::after`,
 * the tick in a selected row, was `#fff` on `--ink`, which in the dark theme
 * is #F0EEF4 — 1.09:1, so a selected row read as an empty one. Same fault on
 * `.sc-mi.on .sc-bx svg`, `.stp .s.done .n` and `.cmpsr .go`. `--on-ink` was
 * already declared in this file for exactly this and never used; `--on-beam`
 * is its pair for the other ground. `.frame2` keeps its white on a brand
 * colour. `.tgl i` kept its white knob under that round's reading that a
 * switch is not a mark; round three measured it at 1.65:1 on the ON track in
 * the dark theme and took the knob to `--on-beam` as well.
 *
 * ---------------------------------------------------------------------------
 * WHAT ROUND TWO CHANGED, IN THE GENERATOR
 * ---------------------------------------------------------------------------
 *
 * One thing: `--line-control`, the input outline. Every field, tick, radio and
 * switch drew its edge in `--line-strong`, which is mock.css's colour for
 * separating one surface from another — 1.52:1 in the light theme and 1.57:1
 * in the dark, against WCAG 1.4.11's 3:1 floor for the thing that says where a
 * control is. The measured table, the hue it was moved along and the list of
 * rules that take it are in the file's own header, three lines below this one.
 * Declared in `docs/superpowers/mockups/ds.css` and copied, per the ruling.
 *
 * ---------------------------------------------------------------------------
 * WHAT ROUND THREE CHANGED, IN THE GENERATOR
 * ---------------------------------------------------------------------------
 *
 * EVERY LITERAL COLOUR IN THIS FILE THAT WAS DECLARED ONCE. Round one caught
 * four white marks; the sweep this round grepped every hex and every rgba in
 * the file, read each one composited against the ground it actually sits on,
 * in both themes, and the list was longer. Nine changed. Each measurement is
 * beside the rule it belongs to; the two that matter most:
 *
 *   .b.dan .ico    #ffb4d8 on --ink            11.01 light / 1.43 dark
 *   .bn.stop       #efbdd6 round --flag-wash    1.47 light / 11.91 dark
 *
 * They are the two directions the same mistake goes. A colour chosen against
 * the light theme either vanishes on the dark one or shouts on it, and which
 * of the two you get is luck.
 *
 * THE FINDING SURFACE IS `.bn.stop`, AND IT KEEPS `--flag-wash`. `ds.py:125`
 * draws it saying "Two findings stop this release", which is the one thing
 * the colour law lets magenta carry. Two other surfaces were sharing that
 * wash and neither is a finding:
 *
 *   - `mock.css:429`'s `.callout.stop`. Every place this product draws it is
 *     a read, a save or a parse that FAILED. Not one is a rule stopping a
 *     release. Seven `.callout.stop` sites in `.tsx` at this head — nine when
 *     G2 counted, five when G3 recounted — and one more is `c-callout stop`
 *     (`rules/Sources.tsx:851`), calm.css's class, which this rule does not
 *     reach and which still paints `--c-flag` on a failed read
 *     (`calm.css:1768-1769`). The body carries the greps that produce both
 *     numbers, because this one has been wrong in three of the four phases
 *     that have written it down.
 *   - this page's own failed-state card (`ds.py:181-185`), which says two
 *     rules were NOT CHECKED — a phrase the rules of engagement name outright
 *     as something magenta may never mean.
 *
 * Both take ink, which is what `.b.dan`, `.fld .in.bad` and `.pv a.dan` in
 * this file already use for grave-and-not-a-finding. `--judge` was the other
 * option the contract offered and it is wrong here: `--judge` means a person
 * must decide, and a failed read is not a decision. `mock.css` may not be
 * edited, so the callout's correction is declared in the generator scoped to
 * `.mockroot` — the signed-in shell root, which contains all nine — and the
 * catalogue draws the callout beside the banner so the pair can be read.
 *
 * HERO 4 NO LONGER DRAWS A BAR. `pitch.py`'s `rules_coverage()` has carried
 * the reason in its own comment since before this card existed — nine rules
 * drawn as a full bar implies a completeness nobody measured, because the bar
 * was scaled to whichever subject happened to have the most rules — and this
 * page had been drawing the bar anyway. The card is what the board shows: the
 * subject, whether anything checks it, and how many rules do. The zero row's
 * `--flag-wash` went with the bar, for the same reason the failed card's did.
 * `system.tsx`'s `CoverageGap` follows the new snippet and its two tests say
 * what the card says rather than how loudly it says it.
 *
 * `.cp b` IS 10.5px, WHICH IS THE PRODUCT'S FLOOR. M1 reported this and could
 * not fix it: `accessibility.test.tsx:491` floors the type at 10.5 and sweeps
 * the Work route that draws the filter chips, and it never saw the rule —
 * that guard builds its stylesheet from `mock.css` and `platform.css` and no
 * other file, so ds.css, pitch.css and calm.css are all invisible to it. Work
 * has been holding the floor with an inline `font-size` on its own `<b>`.
 * Twelve more rules in this file are under the floor and are not touched
 * here; the report lists them with the guard's blind spot.
 */
/* ===========================================================================
   INKSTAND DESIGN SYSTEM — 19 Aug 2026
   Built on src/design/mock.css (spliced unmodified). Nothing here invents a
   colour, a typeface or a radius; it names the controls the platform needs and
   marks which already exist in src/ui/system.tsx.
   ===========================================================================

   ONE COLOUR IS THIS FILE'S OWN, AND IT IS --line-control.

   Every input outline here was drawn in --line-strong, which mock.css tunes to
   separate one surface from another. On a control it is not a separation, it
   is the only thing saying where the control is — and it measured 1.52:1 in
   the light theme and 1.57:1 in the dark, against a 3:1 floor (WCAG 1.4.11,
   non-text contrast). An unchecked tick, an untouched radio and an off switch
   were the boundary cases: nothing else on them draws an edge.

   --line-control is --line-strong moved along its own hue until it clears the
   floor, the way calm.css derived --c-meta. Same hue, same saturation, a
   different lightness: hsl(256 13% 84%) -> hsl(255 13% 57%) in the light
   theme, and hsl(252 12% 25%) -> hsl(251 12% 46%) in the dark, because in the
   dark theme clearing the floor means going up.

   Measured in Chromium, composited, both themes. Ratio against each ground a
   control in this file sits on:

                     surface   surface-2   surface-3   paper   beam-wash
     light, was       1.52       1.46        1.33       1.38     1.34
     light, now       3.56       3.41        3.11       3.22     3.14
     dark, was        1.57       1.49        1.42       1.67     1.39
     dark, now        3.42       3.26        3.10       3.65     3.04

   The two --beam-wash "was" cells read 1.15 and 1.30 until 21 Aug 2026. They
   were wrong, and the round-2 report carries the same pair. Re-measured on the
   catalogue in Chromium, both themes, composited: #D3D0DB on #E8F3F2 is 1.34
   and #3A3746 on #0C2523 is 1.39. Every other cell in the table checks out.

   It is spent on the controls a person has to find and operate: .ck, .rd,
   .tgl, .stp .n, .fld .in, .sr, .cb, .tf and the long menu's .sc-bx. It is
   NOT spent on --line-strong's other work — drawer edges, popovers, banners,
   cards, the empty state's dashed rule — which is a boundary between two
   surfaces and not the identity of a control.

   FOUR CONTROLS KEEP --line-strong UNDER 1.4.11's EXEMPTION, and all four are
   named here rather than two. The exemption is for a component identified by
   other visual means; on each of these that means is a label, so the label's
   own reading is what the exemption rests on. Measured on the catalogue,
   light / dark, label against its own ground:

     .b.sec    "Send for review"        9.14 / 9.37
     .cp       "Needs a person 7"       9.14 / 9.37
     .sg       "Gallery List Board …"  16.37 / 16.81
     .pg-size  "Rows 25"                8.27 / 10.00

   All four draw their edge at 1.38 light / 1.67 dark, and that is a decision
   rather than an omission — the token is declared and it is four more
   substitutions if the director declines the exemption.

   .pg-b is the fifth rule still on --line-strong and it is NOT one of the
   four: it carries a chevron and no label, so nothing else identifies it. Its
   edge reads 1.16 / 1.34. What it rests on instead is the chevron, which is
   the graphical object 1.4.11 actually asks about and measures 4.64 / 4.74.
   =========================================================================== */
/* The catalogue page's own furniture — `html,body`, `.ds*`, the base `.ico` —
   lives in ds-page.css, which ds.py splices and the app never imports.
   `.ds-note` stays here: HERO 4 and the studio inspectors draw it inside a
   component, so it is a label, not page chrome.
   IT IS NO LONGER THE ONE ELEMENT RULE LEFT AT 10, because it is no longer
   mono. What it renders is sentences — "One primary per screen. Danger is
   reserved for acts the register cannot undo." — and a sentence spelled out
   in uppercase mono is the thing the owner threw out. Sans, sentence case,
   11.5. That is over the 10.5 floor and still narrower than what it
   replaces: "Combobox · Swatch · Typeface · Receipt" set in caps at 10 with
   .1em of tracking measured wider than the same words in the sans at 11.5,
   so the three-column `.ds-row` that a 10.5 mono broke holds at this size.
   What is still under the floor here is two `::before` glyphs — the `⚠` on
   `.mockroot .pv a.dan::before` (10) and the `!` on `.mockroot .fld
   .err::before` (9) — marks rather than text, and out of reach of a sweep
   that reads elements. */
.ds-note{font-family:var(--sans);font-size:11.5px;line-height:1.5;
         color:var(--ink-3);width:100%;margin:0 0 10px}
.ico.lg{width:20px;height:20px}

/* ---------------- the controls themselves --------------------------------- */
/* `.mockroot{background:var(--paper)}` is in ds-page.css. On this page it gives
   the catalogue's root a ground; in the app `.mockroot` IS the shell root and
   mock.css already owns its background, so an unlayered copy here was
   repainting the Desk's and Rules' ground from the app's warm paper to this
   file's neutral one. Measured: rgb(113,112,109) -> rgb(110,110,111). */
.b{border-radius:var(--r-sm);font-size:13.5px;font-weight:600;padding:9px 15px;
   display:inline-flex;align-items:center;gap:7px;border:1px solid transparent;cursor:pointer}
.b.pri{background:var(--ink);color:var(--paper)}
.b.sec{background:var(--surface);color:var(--ink-2);border-color:var(--line-strong);font-weight:500}
.b.qui{background:none;color:var(--beam);font-weight:500;padding-left:6px;padding-right:6px}
/* IRREVERSIBLE, not "stopping". --flag marks a rule that stops copy and
   nothing else; a release, a delete or a waiver is grave but it is not a
   finding. Gravity is carried by the ink ground, the warning glyph and the
   consequence spelled out — never by borrowing the finding colour.

   THE GLYPH WAS `#ffb4d8`, WHICH IS BOTH OF THOSE FAULTS AT ONCE. A pink is
   the finding colour by another name, and the literal was declared for one
   theme: on `--ink`, which inverts, it measured 11.01:1 light and 1.43:1
   dark. It takes the label's own ink now, so the glyph reads at the label's
   ratio in both themes and the button's gravity is carried by the three
   things the paragraph above names.

   The 1px inset ring is the same fault at a lower stake: white at 18% over
   `--ink` is 1.74:1 light and 1.03:1 dark, so the edge disappeared with the
   theme. `--paper` is `--ink`'s pair, so the mix holds in both. */
.b.dan{background:var(--ink);color:var(--paper);
       box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--paper) 18%,transparent)}
.b.dan .ico{color:var(--paper)}
.b.dis{background:var(--surface-3);color:var(--ink-4);cursor:not-allowed}
.b.sm{padding:6px 11px;font-size:12.5px}
.b.lg{padding:12px 20px;font-size:15px}
/* A FIELD IS A BLOCK. It was a bare `<span>`, so its computed display was
   `inline` and every vertical margin anything set on it was dropped by the
   box model — `.md .fld`'s 16px below, and the 14px the modal's own markup and
   `system.tsx:5062` both ask for. Measured on the design page: the consequence
   paragraph's bottom and the field's top were the same y, 2388.41, with a
   14px margin computed and none of it rendered. Its label and its input are
   already `display:block`; the wrapper is the one part that was not. Nothing
   moves in a `.ds-row` or a `.md .ft`, which are flex and blockify their items
   regardless. */
.fld{max-width:300px;display:block}
/* A FIELD LABEL IS NOT A READOUT. "Brand name", "Where your rules come from",
   "Anything to note alongside it (optional)" — it names what you type, and
   nobody compares its characters. Sans, sentence case, and one point up to
   12: the tracking and the caps were there to make small mono legible and go
   with it. */
.fld label{display:block;font-family:var(--sans);font-size:12px;
           color:var(--ink-2);margin-bottom:7px}
.fld .in{width:100%;border:1px solid var(--line-control);border-radius:var(--r-sm);
         background:var(--surface);padding:10px 12px;font-size:14px;color:var(--ink)}
.fld .in.foc{border-color:var(--beam);box-shadow:0 0 0 3px var(--beam-wash)}
.fld .in.bad{border-color:var(--flag);box-shadow:0 0 0 3px var(--flag-wash)}
.fld .hint{font-size:12px;color:var(--ink-3);margin-top:6px;display:block}
.fld .err{font-size:12px;color:var(--flag);margin-top:6px;display:block}
.sr{display:flex;align-items:center;gap:9px;border:1px solid var(--line-control);
    border-radius:var(--r-sm);padding:9px 12px;background:var(--surface);min-width:230px}
.sr input{border:0;outline:0;flex:1;font-size:13.5px;background:none;font-family:var(--sans)}
/* `cursor`, the property this set kept missing. On this page a chip is an
   inert `<span>` and reads `auto`; in the app it is a `<button>`, which the
   agent stylesheet gives `default`. Neither says it can be pressed, and a
   filter chip is the most pressable thing on the Work board. pitch.css:164-170
   records the same fix for its own `.cp`/`.chip`. */
.cp{border:1px solid var(--line-strong);border-radius:99px;padding:5px 12px;font-size:12.5px;
    color:var(--ink-2);background:var(--surface);display:inline-flex;align-items:center;gap:6px;
    cursor:pointer}
.cp.on{background:var(--ink);color:var(--paper);border-color:var(--ink);font-weight:600}
/* 10.5, NOT 10. `accessibility.test.tsx:491` floors this product's type at
   10.5px and sweeps `/app/b/:brand/work`, which is the screen that draws the
   filter chips. The floor could not see this rule — the guard loads
   `mock.css` and `platform.css` and no other stylesheet — so Work carries the
   size inline on its own `<b>` instead (`workViews.tsx`, M1 report §3 item 4),
   and that inline style is what has been holding the floor. Declared here, so
   the leaf can drop it and so `Chip` from `system.tsx` becomes usable on Work,
   which is the other half of G1 item 3. */
/* AND NOT `opacity:.7`, WHICH IS WHAT THIS DECLARATION USED TO CARRY.
   Opacity fades a token that was chosen for its contrast and leaves nothing
   that knows what the result measures — the same fault as a disabled button
   drawn at 60%. Composited on `--surface`, `--ink-2` at 70% is 4.01:1 light
   and 5.18:1 dark; the token it is now is 6.11 and 7.36. `--ink-3`, not
   `--ink-2`, because `--ink-3` is what every rule that overrode this one was
   already declaring, in both sheets and on both pages.
   The declaration reached nothing on a shipped screen — every `.cp` in this
   product is inside a `.mockroot`, and `.mockroot .cp b` below neutralised it
   with `opacity:1` — so this is a hazard being removed rather than a defect
   being repaired, and the neutraliser goes with it: two rules that exist only
   to cancel each other are how a sheet stops being readable. */
/* The count riding in the chip — "Everything 11", "Drafts 7". A count is not
   an identifier: it is sans now, and only the face changed. 10.5 stands
   because it is the floor and because the drop from the chip's own 12.5 is
   the hierarchy. */
.cp b{font-family:var(--sans);font-size:10.5px;color:var(--ink-3);font-weight:400;
      font-variant-numeric:tabular-nums}
.sg{display:inline-flex;border:1px solid var(--line-strong);border-radius:var(--r-sm);overflow:hidden}
.sg button{border:0;background:var(--surface);padding:8px 12px;font-size:12.5px;color:var(--ink-2);
           border-right:1px solid var(--line);display:flex;align-items:center;gap:6px}
.sg button:last-child{border-right:0}
.sg button.on{background:var(--ink);color:var(--paper);font-weight:600}
/* A PILL SAYS A STATE, AND A STATE IS A WORD. "Stops a release", "Needs a
   person", "Cleared", "In review", "Archived" — English, so it is set in the
   sans and sentence case, at the size the rest of this file's dense chrome
   takes. The `.tg.mute` variant sometimes carries a rule's citation instead
   ("ABPI 4.2"); one borrowed use does not make the pill a readout, and the
   citation still reads as itself. */
.tg{display:inline-flex;align-items:center;gap:6px;font-family:var(--sans);font-size:12px;
    padding:4px 9px;border-radius:3px}
.tg.stop{background:var(--flag-wash);color:#A4004F}
.tg.judge{background:var(--judge-wash);color:#584A75}
.tg.clear{background:var(--cleared-wash);color:#42561F}
.tg.info{background:var(--beam-wash);color:var(--on-beam-wash)}
.tg.mute{background:var(--surface-3);color:var(--ink-2)}
/* THE RING IS A TOKEN. It was `rgba(23,21,28,.12)` — ink at 12% — which over
   `--surface` in the light theme composites to rgb(227,227,228), within a
   point of `--line` (#E4E2E9), and over `--surface` in the DARK theme
   composites to rgb(21,20,26) against a ground of rgb(22,21,28): 1.01:1, so
   the avatar had no edge at all. Same hairline, declared as the hairline
   token, so it survives the theme flip mock.css:59 performs on every colour
   in this file. `.stk .avx` below already did this with `var(--surface)`. */
.avx{border-radius:50%;background-size:cover;background-position:center;display:inline-block;
     box-shadow:0 0 0 1px var(--line)}
.avx.s{width:22px;height:22px} .avx.m{width:30px;height:30px} .avx.l{width:40px;height:40px}
.stk{display:flex}.stk .avx{margin-left:-8px;box-shadow:0 0 0 2px var(--surface)}
.stk .avx:first-child{margin-left:0}
/* "+4" — how many more people are on this, not which. */
.stk .more{width:22px;height:22px;border-radius:50%;background:var(--surface-3);color:var(--ink-2);
           font-size:10.5px;display:grid;place-items:center;margin-left:-8px;
           box-shadow:0 0 0 2px var(--surface);font-family:var(--sans)}

/* overlays */
.scr{position:relative;height:330px;border:1px solid var(--line);border-radius:var(--r);
     overflow:hidden;background:var(--surface)}
.scr .dim{position:absolute;inset:0;background:rgba(23,21,28,.34)}
.scr .under{padding:18px;filter:saturate(.6)}
.md{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:440px;
    background:var(--surface);border-radius:var(--r-lg);box-shadow:0 24px 60px rgba(23,21,28,.32);
    overflow:hidden}
.md .hd{padding:18px 20px 0}
.md h4{margin:0 0 8px;font-size:17px;letter-spacing:-.01em}
.md p{margin:0;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
/* 14, not the 16 that was here: 16 has never rendered anywhere — the wrapper
   was inline until the rule above — and 14 is what the board's own dialog and
   the shipped `ModalField` have both been asking for. Declaring the value they
   ask for makes the component's inline copy redundant rather than contested. */
.md .fld{margin-top:14px}
.md .hd{padding-bottom:4px}
.md .ft{display:flex;gap:10px;justify-content:flex-end;padding:16px 20px;margin-top:18px;
        border-top:1px solid var(--line);background:var(--surface-2)}
.dr{position:absolute;top:0;right:0;bottom:0;width:340px;background:var(--surface);
    border-left:1px solid var(--line-strong);box-shadow:-16px 0 40px rgba(23,21,28,.14);padding:20px}
.pv{position:absolute;background:var(--surface);border:1px solid var(--line-strong);
    border-radius:var(--r);box-shadow:0 14px 34px rgba(23,21,28,.2);padding:6px;min-width:190px}
.pv a{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:var(--r-sm);
      font-size:13.5px;color:var(--ink);text-decoration:none}
.pv a.dan{color:var(--flag)}
.pv .sep{height:1px;background:var(--line);margin:5px 0}
.ts{position:absolute;left:18px;bottom:18px;background:var(--ink);color:var(--paper);border-radius:var(--r);
    padding:12px 15px;display:flex;align-items:center;gap:11px;font-size:13.5px;
    box-shadow:0 12px 30px rgba(23,21,28,.3)}
.ts .u{color:var(--on-beam-wash);font-weight:600;margin-left:6px}
/* `font-weight` and `margin-bottom` are declared on `.bn` and `.tt` because
   mock.css names both — `.brandcard .bn:362` at 17px/600 and `.toast .tt:392`
   at 14px/600 with a 4px gap. Neither can be beaten from here: mock's are
   (0,2,0) and these are (0,1,0), so a ds `Banner` inside a `.brandcard`, or a
   ds tooltip inside a mock `.toast`, still loses the two properties mock
   declares. Nothing in the product renders either wrapper (0b report §4,
   confirmed by querySelectorAll on four routes), so this is a hazard rather
   than a defect, and it is the one collision in this pass that a property set
   cannot close. It is in the report. */
.bn{border:1px solid var(--line-strong);border-radius:var(--r);padding:13px 16px;
    display:flex;align-items:center;gap:13px;background:var(--surface-2);font-size:13.5px;
    font-weight:400}
/* THE EDGES WERE HAND-PICKED AGAINST THE LIGHT WASH AND STAYED THERE. A wash
   flips with the theme and a literal does not. A banner's background paints
   under its own border, so the ground each edge is read against is that
   banner's wash — measured that way, light then dark:

     `.bn.stop`  `#efbdd6` on `--flag-wash`   1.42 → 10.92
     `.bn.info`  `#bcdedb` on `--beam-wash`   1.27 → 11.20
     `.bn`       `--line-strong` on `--surface-2`  1.46 / 1.49

   A hairline on the light page and, on the dark one, a pale pink wire blazing
   round a near-black banner, louder than the sentence inside it. Not
   invisible: the opposite.

   Derived from the wash's own hue instead, so the edge turns over with the
   ground it sits on. The percentages are the ones that hold the hairline in
   both themes: stop 1.40 / 1.31, info 1.28 / 1.53, against the plain banner's
   1.46 / 1.49. */
.bn.stop{background:var(--flag-wash);border-color:color-mix(in srgb,var(--flag) 20%,var(--flag-wash))}
.bn.info{background:var(--beam-wash);border-color:color-mix(in srgb,var(--beam) 18%,var(--beam-wash))}
/* THE FOURTH RANK. A screen waiting on a named person — an invite nobody has
   accepted, a release nobody has signed, a finding no machine can settle —
   had two ranks to choose between and both said something false: `stop`,
   which claims a rule blocks the release, or the plain banner, which says
   this is administrative. `system.tsx` wrote the two declarations at its own
   leaf and said so, which is how two stylesheets start disagreeing. Same
   recipe as the two above — the wash as the ground, the edge mixed from the
   wash's own hue at `.bn.stop`'s 20%, so it turns over with the theme instead
   of being a literal picked against one of them. Measured edge against its
   own wash: 1.30 light / 1.45 dark, inside the band the other three hold
   (stop 1.40 / 1.31, info 1.28 / 1.53, plain 1.46 / 1.49). */
.bn.judge{background:var(--judge-wash);border-color:color-mix(in srgb,var(--judge) 20%,var(--judge-wash))}
/* A READ THAT FAILED IS NOT A FINDING.
   `.bn.stop` above is the finding banner — `ds.py:125` draws it saying "Two
   findings stop this release", which is the one sentence the colour law lets
   magenta carry. `.callout.stop` shared that wash and is a different fact:
   every place this product draws it says a read, a save or a parse FAILED —
   "could not be read", "Not filed", "That did not go through", "Not created",
   "Not done", "That seat was not changed". Not one of them is a rule stopping
   a release, and "not checked" is on the law's list of things magenta may
   never mean.

   SEVEN, counted with the grep this sentence describes rather than carried
   forward. It was nine when G2 wrote it, five when G3 recounted, and it is
   seven now — the number moves every phase, so the command is written down
   beside it:

     $ grep -rn "callout stop" src --include='*.tsx' | grep -v c-callout | wc -l
            7
     $ grep -rn "c-callout stop" src --include='*.tsx' | wc -l
            1

   `parts.tsx:270`, `Brands.tsx:844`, `signalBrand.tsx:183`, `People.tsx:504`,
   `People.tsx:689`, `dropTarget.tsx:359`, `CopyCreation.tsx:186`.
   `FirstRun.tsx`'s callout is gone with the screen Phase 3 retired — the file
   itself is still here, 2240 lines of it, and draws no callout at all — while
   `signalStandards.tsx` and `Signals.tsx` went with their screens entirely.
   The three on `Brands` and `People` are new since G3 and every one of them is
   a failed act, which is what the sentence above claims about all of them.

   `importWizard.tsx` did NOT go — the screen is still here and its two
   callouts are `callout judge` now (`importWizard.tsx:560`, `:1194`), which is
   what a step waiting on a person should be.

   The remaining `c-callout stop` is `rules/Sources.tsx:851`, a different class
   on a different sheet (`calm.css:1768-1769`) that this selector does not
   reach, and it still puts `--c-flag` on the title of a failed read. calm.css
   is not this file's to edit; §15 of the G3 report hands it to the contract
   that retires calm.css. G2's list also named `Rules.tsx:1092`, `HouseRules.tsx:238`
   and `ControlMap.tsx:199`: the first no longer draws one and the other two
   are files that no longer exist.

   `mock.css:429` owns the rule and may not be edited, so the correction is
   declared here and scoped to `.mockroot`, which is the signed-in shell root
   and contains all five of them. Ink, not `--judge`: `--judge` means
   a person must decide, and a failed read is not a decision. Ink is what
   `.b.dan`, `.fld .in.bad` and `.pv a.dan` in this file already use for grave
   and not a finding, and a 2px ink spine down the left is louder than the
   pink one it replaces, which is what `parts.tsx:213-222` asks for. */
.mockroot .callout.stop{background:var(--grad-surface)}
.mockroot .callout.stop::before{background:var(--ink)}
.tt{position:absolute;background:var(--ink);color:var(--paper);font-size:12px;padding:6px 9px;
    border-radius:5px;white-space:nowrap;font-weight:400;margin-bottom:0}
/* table with selection + bulk bar */
.tb{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.tb .h,.tb .r{display:grid;grid-template-columns:34px 1fr 130px 110px 96px;gap:14px;align-items:center;
              padding:11px 16px}
/* `.h` IS A COLUMN HEADER HERE AND A RESIZE HANDLE IN THE EDITOR.
   `bench.css:848` declares `.h` bare — `position:absolute`, 9x9, a `--beam`
   ground, a white 1.5px border, `z-index:15`, `pointer-events:auto`, and a
   `::after` that gives it a 21px hit target — and that file is loaded on every
   signed-in route. Measured on /app?preview with this card's markup injected:
   the header row came out absolutely positioned, 34x24, radius 2, at z-index
   15. The nine declarations below are what this page computes; `border:0`
   comes before `border-bottom` because the handle's border is all four sides
   and this row only wants one. */
/* And a column header is furniture: "Piece", "Brand", "Signed by",
   "Findings". Sans, sentence case, 12 — uppercase mono on a header spends
   the identifier voice on a label and makes every table in the product look
   like a terminal. */
.tb .h{background:var(--surface-2);border:0;border-bottom:1px solid var(--line);border-radius:0;
       position:static;inset:auto;width:auto;height:auto;z-index:auto;pointer-events:auto;
       font-family:var(--sans);font-weight:600;
       font-size:12px;color:var(--ink-3)}
.tb .h::after{content:none}
.tb .r{border-bottom:1px solid var(--line-soft);font-size:13.5px}
.tb .r.sel{background:var(--beam-wash)}
.tb .r:last-child{border-bottom:0}
.ck{width:15px;height:15px;border-radius:4px;border:1.5px solid var(--line-control);
    background:var(--surface);display:block}
.ck.on{background:var(--ink);border-color:var(--ink);position:relative}
/* THE TICK IS ON --ink, WHICH INVERTS. It was a hard #fff, so in the dark
   theme a near-white check sat on a near-white box at 1.09:1 and a selected
   row read as an empty one. --on-ink is the pair this file already declares
   for exactly this; it was defined and never used. */
.ck.on::after{content:'';position:absolute;left:4px;top:1px;width:4px;height:8px;
              border:solid var(--on-ink);border-width:0 2px 2px 0;transform:rotate(45deg)}
.bulk{background:var(--ink);color:var(--paper);border-radius:var(--r);padding:10px 14px;display:flex;
      align-items:center;gap:14px;font-size:13.5px;margin-bottom:12px}
.bulk .b{padding:6px 11px;font-size:12.5px}
.bulk .b.sec{background:color-mix(in srgb,var(--paper) 18%,transparent);border-color:transparent;color:var(--paper)}
/* states */
.stt{border:1px dashed var(--line-strong);border-radius:var(--r-lg);padding:34px;text-align:center;
     background:var(--surface)}
/* THE GLYPH HAS TO SAY IT IS INLINE, because the app it ships into resets
   `svg` and the page it was drawn on does not. `.stt` centres its contents
   with `text-align`, and the base `.ico` (mock.css:96, ds-page.css:50) sets no
   `display` — so here the svg is inline and the centring reaches it, while in
   the product Tailwind's preflight sets `svg{display:block}` and a block box
   ignores its parent's `text-align`. Measured on the ported Home: display
   block, box at x=65 inside a card starting at x=30. `Desk.tsx:1056` centres
   it by hand and says this declaration is what it is standing in for (P1
   report, concern 1). An svg is a replaced element, so inline-block is the
   layout it already had on this page. */
.stt>.ico{display:inline-block}
/* THE FAILED STATE IS THE SAME FACT AS `.callout.stop`. This card says two
   rules were NOT CHECKED, and it was drawn on `--flag-wash` behind a `#efbdd6`
   edge written inline in `ds.py`. Both are gone: the wash because "not
   checked" is on the colour law's list, the literal because it was a
   one-theme colour (1.47:1 light, 11.91:1 dark). A solid ink edge against the
   dashed `--line-strong` the other three states carry is what separates it. */
.stt.fail{border-style:solid;border-color:var(--ink);background:var(--surface)}
.stt h5{margin:12px 0 5px;font-size:15px}
.stt p{margin:0 0 14px;font-size:13px;color:var(--ink-2)}
.sk{background:linear-gradient(90deg,var(--surface-3) 25%,var(--surface-2) 50%,var(--surface-3) 75%);
    border-radius:4px;height:11px;display:block;margin-bottom:9px}
.sk.t{width:38%;height:15px;margin-bottom:14px}
.sk.s{width:62%}

/* ===========================================================================
   PART TWO — the components the studios need, and the ones the platform
   still lacks. Same tokens. The studios already have `capsule`, `composer`,
   `tip-below`, `notice` and `iconbtn`; these give them one definition instead
   of five.
   =========================================================================== */
.cmp{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px}
/* toggles, radios, checks */
.tgl{width:36px;height:20px;border-radius:99px;background:var(--line-control);position:relative;
     display:inline-block}
/* THE KNOB IS THE SWITCH. `#fff` held on the off track (`--line-control`,
   3.56:1 light / 5.30:1 dark) and failed on the on track: white on `--beam`
   is 5.54:1 light and **1.65:1** dark, under 1.4.11's 3:1 for the graphical
   object that says which way the switch is thrown. `--on-beam` is the pair
   this file already declares for that ground, and it holds on both tracks:
   3.22 / 3.65 off, 5.01 / 11.70 on. Light loses half a point off the knob
   because `--paper` is #F4F3F6 rather than white; it stays over the floor,
   and the dark on-state is the reading this change exists for. This file's
   header used to say the white knob was kept deliberately, "a switch rather
   than a mark"; the measurement above is why that line is gone. */
.tgl i{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
       background:var(--on-beam);box-shadow:0 1px 3px rgba(0,0,0,.25);display:block}
.tgl.on{background:var(--beam)} .tgl.on i{left:18px}
.rd{width:16px;height:16px;border-radius:50%;border:1.5px solid var(--line-control);display:inline-block;
    position:relative;background:var(--surface)}
.rd.on{border-color:var(--ink)}
.rd.on::after{content:'';position:absolute;inset:3px;border-radius:50%;background:var(--ink)}
.opt{display:flex;align-items:center;gap:10px;padding:9px 0;font-size:13.5px}
/* stepper */
.stp{display:flex;align-items:center;gap:0}
.stp .s{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--ink-3)}
.stp .s.on{color:var(--ink);font-weight:600}
/* The step's number in its ring. One digit, centred by the grid — nothing to
   compare, so nothing to spell out. */
.stp .n{width:22px;height:22px;border-radius:50%;border:1.5px solid var(--line-control);
        display:grid;place-items:center;font-family:var(--sans);font-size:11.5px}
.stp .s.on .n{background:var(--ink);color:var(--paper);border-color:var(--ink)}
/* Same fault on the other ground: --beam goes #0B756F -> #22E0D5 in the dark
   theme, and a white tick on bright cyan is 1.5:1. */
.stp .s.done .n{background:var(--beam);border-color:var(--beam);color:var(--on-beam)}
.stp .bar{width:44px;height:1px;background:var(--line-strong);margin:0 12px}
/* combobox */
.cb{border:1px solid var(--line-control);border-radius:var(--r-sm);background:var(--surface);
    width:280px;overflow:hidden}
.cb .top{display:flex;align-items:center;gap:9px;padding:9px 12px;border-bottom:1px solid var(--line)}
.cb .o{display:flex;align-items:center;gap:10px;padding:8px 12px;font-size:13.5px;
       border-bottom:1px solid var(--line-soft)}
.cb .o:last-child{border-bottom:0}
.cb .o.on{background:var(--beam-wash)}
/* "4 rules" against the option it belongs to — a count, and it has a noun. */
.cb .o .c{margin-left:auto;font-family:var(--sans);font-size:12px;color:var(--ink-3)}
.cb .o.new{background:var(--surface-2);color:var(--ink-2)}
/* swatch + typeface pickers, used by the brand kit */
/* The row, not a swatch. `bench.css` also declares `.sw` bare — a 26x26
   button with a white 18%-alpha border and `cursor:pointer` — so on an app
   route this radiogroup collapsed into one 26px square (measured on
   /app?preview). `system.tsx:3710` is a `<span role="radiogroup">` holding
   buttons; the pointer belongs to them. */
.sw{display:flex;gap:8px;width:auto;height:auto;border:0;border-radius:0;padding:0;cursor:auto}
.sw i{width:30px;height:30px;border-radius:6px;display:block;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}
.sw i.on{box-shadow:0 0 0 2px var(--ink),inset 0 0 0 1px rgba(0,0,0,.08)}
.tf{border:1px solid var(--line-control);border-radius:var(--r-sm);padding:10px 13px;background:var(--surface);
    display:inline-flex;flex-direction:column;gap:3px;min-width:120px}
.tf b{font-size:19px;font-weight:500;line-height:1}
/* The typeface's name under its specimen — "Sohne", "Tiempos". A name. */
.tf span{font-family:var(--sans);font-size:12px;color:var(--ink-3)}
.tf.on{box-shadow:0 0 0 2px var(--ink)}
/* key–value receipt, used by Record and sign-off */
.kvl{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--surface)}
.kvl div{display:flex;justify-content:space-between;padding:10px 14px;font-size:13px;
         border-bottom:1px solid var(--line-soft)}
.kvl div:last-child{border-bottom:0}
.kvl span:first-child{color:var(--ink-2)}
.kvl .mono{font-family:var(--mono);font-size:11.5px}
/* the studio surfaces */
.stg{position:relative;height:300px;border:1px solid var(--line);border-radius:var(--r);
     overflow:hidden;background:var(--surface)}
.stg .doc{padding:30px 34px;font-size:16px;line-height:1.8;max-width:44ch}
.u-stop{text-decoration:underline wavy var(--flag);text-underline-offset:5px;
        text-decoration-thickness:1.8px;text-decoration-skip-ink:none}
.u-judge{text-decoration:underline wavy var(--judge);text-underline-offset:5px;
         text-decoration-thickness:1.8px;text-decoration-skip-ink:none}
/* the floating selection capsule the studios already have */
.cap2{position:absolute;background:var(--ink);border-radius:8px;padding:5px;display:flex;gap:2px;
      box-shadow:0 10px 26px rgba(23,21,28,.34)}
.cap2 button{border:0;background:none;color:var(--paper);padding:6px 9px;border-radius:5px;font-size:12.5px;
             display:flex;align-items:center;gap:6px}
/* WHITE ON `--ink` IS A ONE-THEME COLOUR. The capsule's ground is `--ink`,
   which inverts; a white wash on it measured 1.62:1 light / 1.02:1 dark for
   the pressed button and 1.87:1 / 1.03:1 for the separator, so in the dark
   theme the capsule was one flat slab with no pressed state and no divider.
   `--paper` is the pair `--ink` already has. */
.cap2 button.on{background:color-mix(in srgb,var(--paper) 16%,transparent)}
.cap2 .sep{width:1px;background:color-mix(in srgb,var(--paper) 20%,transparent);margin:4px 3px}
/* a finding attached to the words */
.fpop{position:absolute;width:290px;background:var(--surface);border:1px solid var(--line-strong);
      border-radius:var(--r);box-shadow:0 14px 34px rgba(23,21,28,.2);padding:13px 15px}
.fpop::before{content:'';position:absolute;top:-6px;left:34px;width:10px;height:10px;
              background:var(--surface);border-left:1px solid var(--line-strong);
              border-top:1px solid var(--line-strong);transform:rotate(45deg)}
.fpop q{display:block;font-family:var(--serif);font-size:14px;line-height:1.42;quotes:none;margin:8px 0 0}
/* margin note, the studio's quiet annotation */
.mn{position:absolute;right:14px;width:172px;border-left:2px solid var(--line-strong);
    padding-left:11px;font-size:12px;line-height:1.5;color:var(--ink-2)}
.mn.stop{border-left-color:var(--flag)}
/* the composer the two studios share */
.cmpsr{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);width:min(520px,86%);
       background:var(--ink);border-radius:12px;padding:11px 13px;display:flex;align-items:center;
       gap:11px;box-shadow:0 14px 34px rgba(23,21,28,.32)}
.cmpsr input{flex:1;border:0;background:none;outline:0;color:var(--paper);font-size:14px;font-family:var(--sans)}
/* Same ground, same fault: 6.13:1 light and 1.08:1 dark, so the composer had
   no prompt in the dark theme. `.cmpsr .kbd` two lines below already mixes
   `--paper`; this is the one that was missed.

   AND 55% WAS NOT FAR ENOUGH. It was shipped as the repaired value at 4.12:1
   dark, which is under AA — a placeholder is text and takes 4.5, not the 3:1
   a hairline takes. 62% is the mix `.kbd` on the next line has been using all
   along, on this exact ground, so this is one value on the composer rather
   than two: 6.86:1 light, 5.20:1 dark, computed against the composited
   `--ink` ground with `color-mix()` read as `color(srgb …)` — its channels
   are 0..1 and reading them as 8-bit is what overstated a 7.07 as 11.76. */
.cmpsr input::placeholder{color:color-mix(in srgb,var(--paper) 62%,transparent)}
.cmpsr .go{width:28px;height:28px;border-radius:50%;background:var(--beam);display:grid;
           place-items:center;color:var(--on-beam)}
.cmpsr .kbd{font-family:var(--mono);font-size:10.5px;color:color-mix(in srgb,var(--paper) 62%,transparent)}
/* The status line every studio ends with. It speaks English — "One thing
   stops a release; one more wants a look." beside "68 words · saved · 14
   rules in force" — so it is set in English's face. Sans at 12, which is
   where a sentence this long stops being squinted at. */
.sl{position:absolute;left:0;right:0;bottom:0;height:32px;border-top:1px solid var(--line);
    background:var(--surface);display:flex;align-items:center;padding:0 14px;
    font-family:var(--sans);font-size:12px;color:var(--ink-2);gap:9px}
.sl .r{margin-left:auto}
.sl .dot{width:6px;height:6px;border-radius:50%;background:var(--flag);display:block}
/* frame filmstrip */
.fs{display:flex;gap:6px;align-items:flex-end}
.fs i{width:38px;height:48px;border-radius:3px;background:var(--surface-3);
      border:1px solid var(--line-strong);display:block}
.fs i.on{outline:2px solid var(--ink);outline-offset:1px}
.fs i.flag{border-color:var(--flag);border-width:2px}
.fs .add{width:26px;height:48px;border:1px dashed var(--line-strong);border-radius:3px;
         display:grid;place-items:center;color:var(--ink-3)}

/* ---------------------------------------------------------------------------
   CONTRAST FLOOR. Appended last so nothing later overrides it. Every value
   measured, not judged: --cleared on white is 4.45:1, just under AA, and text
   on a brand ground was being dimmed by opacity.
   --------------------------------------------------------------------------- */
/* `.mockroot .tg.clear{color:#3F5622}` stood here and had not applied since
   the wash-text pair landed: the same selector at the same specificity is
   declared later in this file with `--on-cleared-wash`, and later wins.
   Measured before removing it — #42561f light, #cdf177 dark, both times the
   token — so this is a dead literal coming out, not a colour change. */
/* The five rules that stood here named `.art-f`, `.col h6`, `.lbl`,
   `.vB-card .m` and `.m` — none of which this page draws. They are the pitch
   board's, they are already in pitch.css (:307-311), and unscoped here they
   reached into the app: `.mockroot .m` repainted the Desk's away rows. */

/* ===========================================================================
   PART THREE — full studio screens, and the hero components.
   =========================================================================== */
.full{height:900px;display:flex;flex-direction:column;background:var(--paper)}
.full .top{height:52px;background:var(--surface);border-bottom:1px solid var(--line);
           display:flex;align-items:center;gap:14px;padding:0 18px;flex:none}
/* "Northwind Dermatology · Veltriva HCP email · rev 3". Two names and a
   revision, and the names are most of it — so the line is sans and the
   revision is carried by the words "rev 3" rather than by a second face.
   When a crumb gets its own element for the revision, that element takes
   `.mono`; a whole breadcrumb never does. */
.full .crumb{font-family:var(--sans);font-size:12.5px;color:var(--ink-2)}
.full .crumb b{color:var(--ink)}
.full .acts{margin-left:auto;display:flex;align-items:center;gap:10px}
.full .mid{flex:1;display:grid;overflow:hidden}
.full .rail{width:52px;border-right:1px solid var(--line);background:var(--surface);
            display:flex;flex-direction:column;align-items:center;gap:6px;padding-top:12px}
.full .rail button{width:34px;height:34px;border-radius:var(--r-sm);border:0;background:none;
                   color:var(--ink-2);display:grid;place-items:center}
.full .rail button.on{background:var(--surface-3);color:var(--ink)}
.full .canvas{background:var(--paper);position:relative;overflow:hidden;display:flex;
              align-items:center;justify-content:center}
.full .insp{width:326px;border-left:1px solid var(--line);background:var(--surface);
            padding:20px 18px;overflow:hidden}
/* `min-height:0` is the load-bearing one: `bench.css`'s bare `.status` sets
   `min-height:44px`, which beats a 34px height rather than losing to it, and
   `position:relative;z-index:22` on a bar that is not stacked.
   Its type is `.sl`'s, for `.sl`'s reason: the bar says a sentence. */
.full .status{height:34px;min-height:0;border-top:1px solid var(--line);background:var(--surface);display:flex;
              align-items:center;flex-wrap:nowrap;position:static;z-index:auto;
              padding:0 16px;font-family:var(--sans);font-size:12px;
              color:var(--ink-2);gap:9px;flex:none}
.full .status .r{margin-left:auto}
.paper2{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-3);
        padding:46px 54px;width:600px}
.paper2 h3{font-size:23px;margin:0 0 22px;letter-spacing:-.02em}
.paper2 p{font-size:17px;line-height:1.8;margin:0 0 18px;color:var(--ink)}
.frame2{width:430px;aspect-ratio:4/5;border-radius:6px;box-shadow:var(--shadow-3);padding:34px;
        display:flex;flex-direction:column;color:#fff;position:relative}
.frame2 .hl2{font-family:var(--serif);font-size:38px;line-height:1.1;margin:0}
.frame2 .ft2{margin-top:auto;display:flex;align-items:center;gap:9px;font-size:11px;
             letter-spacing:.1em;text-transform:uppercase;color:#fff}
.frame2 .bm2{width:20px;height:20px;border-radius:5px;background:rgba(255,255,255,.92)}

/* ---- HERO 1 · the finding ------------------------------------------------ */
.hero-find{background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--r-lg);
           overflow:hidden;box-shadow:var(--shadow-2);max-width:620px}
.hero-find .words{padding:26px 28px;font-size:20px;line-height:1.72;border-bottom:1px solid var(--line)}
.hero-find .rule{padding:18px 28px;display:flex;gap:16px;align-items:flex-start;
                 border-left:3px solid var(--flag);background:var(--flag-wash)}
.hero-find .rule q{font-family:var(--serif);font-size:16px;line-height:1.44;quotes:none;margin:0;
                   display:block;color:var(--ink)}
/* Where the rule came from and what it has caught: "ABPI 4.2 · adopted 6 Aug
   by Tomasz W · caught 4 times in 90 days". A citation, a date, a name and a
   count — a provenance line, which is metadata and reads as a sentence. Sans
   at 12; the colour is untouched. */
.hero-find .rule .src2{font-family:var(--sans);font-size:12px;
                       color:#8A2A5E;display:block;margin-top:8px}
.hero-find .acts2{padding:14px 28px;display:flex;gap:10px;background:var(--surface-2);
                  border-top:1px solid var(--line)}

/* ---- HERO 2 · the seal --------------------------------------------------- */
.seal{width:340px;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--r);
      padding:22px 24px;box-shadow:var(--shadow-3);position:relative;overflow:hidden}
.seal::before{content:'';position:absolute;left:0;right:0;top:0;height:4px;background:var(--thread)}
.seal .who2{display:flex;align-items:center;gap:11px;padding-bottom:14px;
            border-bottom:1px solid var(--line)}
.seal .who2 b{font-size:14px}
/* "released 18 Aug 2026 · 14:22 UTC", under the name that released it. A
   timestamp is a fact about when, not a thing to spell out. */
.seal .who2 span{font-family:var(--sans);font-size:12px;color:var(--ink-3);display:block;margin-top:3px}
.seal .line{display:flex;justify-content:space-between;padding:8px 0;font-size:12.5px}
.seal .line span:first-child{color:var(--ink-2)}
.seal .line .mono2{font-family:var(--mono);font-size:11px}
/* `overflow-wrap:anywhere`, not `word-break:break-all`. The line is a hash
   AND a sentence — "…a91d — the exact words this covers" — and break-all
   splits both: at 10.5px in this 340px card it put "th" at the end of one
   line and "is covers" on the next. Anywhere breaks the hash where it has to
   and leaves the words alone. */
.seal .hash{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line-strong);
            font-family:var(--mono);font-size:10.5px;color:var(--ink-3);overflow-wrap:anywhere;
            line-height:1.5}

/* ---- HERO 3 · the rule card --------------------------------------------- */
.rulecard{width:340px;background:var(--surface);border:1px solid var(--line-strong);
          border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-2)}
.rulecard .body2{padding:20px 22px}
.rulecard q{font-family:var(--serif);font-size:18px;line-height:1.42;quotes:none;display:block;
            color:var(--ink)}
.rulecard .prov2{margin-top:16px;padding-top:14px;border-top:1px solid var(--line-soft);
                 display:flex;flex-direction:column;gap:8px}
.rulecard .prov2 div{display:flex;justify-content:space-between;font-size:12px}
.rulecard .prov2 span:first-child{color:var(--ink-2)}
/* `bench.css`'s bare `.strip` is the filmstrip drawer — 86px, `flex:none`,
   `position:relative`, `z-index:20`, `overflow:hidden` and a height
   transition. This is a 5px rule across the top of a card. */
.rulecard .strip{height:5px;background:var(--flag);flex:0 1 auto;position:static;z-index:auto;
                 overflow:visible;transition:none}
.rulecard.warn .strip{background:var(--judge)}

/* ---- HERO 4 · coverage gap ----------------------------------------------
   `.covgap`, not `.gap`. ds.css ships to the app unscoped, and the Rules
   filter row draws `<i class="c-gut gap">` (src/design/table.tsx:975 with
   calm.css:1979): a 3px gutter tick was taking this card's 22px/24px padding
   and standing the chip up at 58px. */
.covgap{width:100%;max-width:560px;background:var(--surface);border:1px solid var(--line-strong);
     border-radius:var(--r-lg);padding:22px 24px}
/* NO BAR, AND NO FLAG ON THE ZERO ROW.
   This card drew a proportional bar per subject and painted the zero row in
   `--flag-wash` with a 3% stub. `pitch.py`'s Coverage board has forbidden the
   first in its own comment since it was written — nine rules drawn as a full
   bar implies a completeness nobody measured, because the bar was scaled to
   whichever subject happened to have the most rules — and the colour law
   forbids the second: "not checked" is on its list of things magenta may
   never mean. The reference board and this page had been disagreeing about
   the same card.

   It is what the board draws now: the subject, whether anything checks it,
   and how many rules do. The pills are `.tg`, so there is one definition of a
   pill rather than a second one here. `.tg.clear` on "Checked" is the
   coverage question answered, not a release outcome — nothing on this card
   says a piece passed anything. */
.covgap .g1{display:grid;grid-template-columns:1fr 116px 74px;gap:14px;align-items:center;padding:7px 0}
.covgap .g1>.tg{justify-self:start}
/* "9 rules", "1 rule", "0 rules" — a count with its noun, right-aligned.
   `tabular-nums` keeps the column true now that the face does not do it. */
.covgap .g1 b{font-family:var(--sans);font-size:12px;color:var(--ink-2);text-align:right;
              font-weight:400;font-variant-numeric:tabular-nums}

/* DISABLED, READABLE.
   `.b.dis` was the primary button at reduced opacity, which composites the
   white label toward its own dark ground and lands at 1.75:1. A disabled
   control still has to be legible — it is unavailable, not absent. */
.mockroot .b.dis,.mockroot .b.dis:hover{
  background:var(--surface-3);border:1px solid var(--line);color:var(--ink-3);
  opacity:1;cursor:not-allowed;box-shadow:none}

/* the last sub-AA reading: a 10px numeral at --ink-4 on a WHITE card.
   Scoped to the card, because .cp also sits on the dark page ground where
   ink-2 would be the unreadable one. */
/* the catalogue-card floor for `.cp` moved to ds-page.css */

/* ======================= 20 · SCALE ==========================
   Prefixed sc- throughout: mock.css already owns .pop, .menu, .tip,
   .modal, .drawer and .tbl, and a collision here would restyle the
   product's real chrome. */
.mockroot .sc-pop{display:inline-flex;flex-direction:column;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-md);box-shadow:0 18px 42px rgba(23,21,28,.19);
  overflow:hidden;vertical-align:top}
.mockroot .sc-hd{padding:9px;border-bottom:1px solid var(--line-soft);flex:none}
.mockroot .sc-srch{display:flex;align-items:center;gap:7px;padding:7px 9px;border-radius:var(--r-sm);
  background:var(--surface-3);color:var(--ink-3);font-size:13px}
.mockroot .sc-srch i{font-style:normal}
.mockroot .sc-srch svg{width:14px;height:14px}
/* 288px = eight rows at 36. The ninth sits half-cut, which is what tells a
   person the list continues without needing a scrollbar to say so. */
.mockroot .sc-body{max-height:288px;overflow-y:auto;padding:5px;display:block}
.mockroot .sc-mi{display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:var(--r-sm);
  cursor:default}
.mockroot .sc-mi:hover{background:var(--surface-3)}
.mockroot .sc-mi.on{background:var(--beam-wash)}
.mockroot .sc-mi.dan{color:var(--flag)}
.mockroot .sc-bx{width:15px;height:15px;border:1px solid var(--line-control);border-radius:3px;
  flex:none;display:grid;place-items:center;background:var(--surface)}
.mockroot .sc-mi.on .sc-bx{background:var(--ink);border-color:var(--ink)}
.mockroot .sc-mi.on .sc-bx svg{width:10px;height:10px;color:var(--on-ink)}
.mockroot .sc-mt{display:flex;flex-direction:column;gap:1px;min-width:0}
.mockroot .sc-mt b{font-size:13px;font-weight:500;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
/* THE ONE MONO ON THIS MENU, and it is the citation: "ABPI 4.2", "EADV 26",
   "House 08". Somebody scanning a rule list is comparing 4.2 against 4.1 and
   4.6 character by character, which is the whole of the test. The rule's own
   words, on the line above, are sans. */
.mockroot .sc-mt i{font:500 10.5px/1.2 var(--mono);letter-spacing:.08em;color:var(--ink-3);
  font-style:normal;text-transform:uppercase}
.mockroot .sc-sep{display:block;height:1px;background:var(--line-soft);margin:5px 8px}
.mockroot .sc-ft{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 10px;border-top:1px solid var(--line-soft);background:var(--surface-2);flex:none}
/* "2 selected", in the menu's foot. A count of what you are holding. */
.mockroot .sc-ft b{font:600 12px/1.2 var(--sans);color:var(--ink-2)}

/* tooltips wrap, they do not run */
.mockroot .sc-tipwrap{display:inline-flex;flex-direction:column;gap:7px;align-items:flex-start}
.mockroot .sc-tip{display:inline-block;background:var(--ink);color:var(--paper);font-size:12.5px;
  line-height:1.45;padding:7px 10px;border-radius:var(--r-sm);max-width:260px;
  box-shadow:0 8px 22px rgba(23,21,28,.24)}
.mockroot .sc-tip.wide{max-width:260px}
.mockroot .sc-tip.over{opacity:.45}
/* The board's own note on a specimen that overruns — "TOO LONG — THIS IS A
   POPOVER". The caps are in the words, so the rule does not need to add
   them, and an annotation is a phrase. */
.mockroot .sc-flagnote{font:600 11px/1.3 var(--sans);color:var(--flag)}

/* modal and drawer: the middle scrolls, the ends do not */
.mockroot .sc-two{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:start}
.mockroot .sc-scrim{display:block;background:rgba(23,21,28,.42);border-radius:var(--r-md);
  padding:26px}
.mockroot .sc-modal,.mockroot .sc-drw{display:flex;flex-direction:column;background:var(--surface);
  border-radius:var(--r-md);overflow:hidden;box-shadow:0 22px 54px rgba(23,21,28,.3);
  max-height:330px}
.mockroot .sc-drw{border:1px solid var(--line);box-shadow:0 12px 34px rgba(23,21,28,.14)}
.mockroot .sc-mhd{display:flex;align-items:center;gap:10px;padding:13px 15px;flex:none;
  border-bottom:1px solid var(--line-soft)}
.mockroot .sc-mhd b{font-size:14.5px;font-weight:600;color:var(--ink)}
.mockroot .sc-x,.mockroot .sc-xbtn{margin-left:auto;width:26px;height:26px;border-radius:var(--r-sm);
  display:grid;place-items:center;color:var(--ink-2);cursor:pointer}
.mockroot .sc-xbtn{margin-left:0;border:1px solid var(--line-strong)}
.mockroot .sc-x:hover,.mockroot .sc-xbtn:hover{background:var(--surface-3);color:var(--ink)}
.mockroot .sc-x svg,.mockroot .sc-xbtn svg{width:14px;height:14px}
.mockroot .sc-mbody{overflow-y:auto;padding:14px 15px;flex:1;min-height:0}
.mockroot .sc-mbody p{margin:0 0 11px;font-size:13px;line-height:1.55;color:var(--ink-2)}
.mockroot .sc-mbody p b{color:var(--ink);font-weight:600}
.mockroot .sc-mft{display:flex;align-items:center;gap:8px;padding:11px 14px;flex:none;
  border-top:1px solid var(--line-soft);background:var(--surface-2)}

/* the ways out */
.mockroot .sc-back{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:500;
  color:var(--ink-2);cursor:pointer}
.mockroot .sc-back:hover{color:var(--ink)}
.mockroot .sc-back svg{width:14px;height:14px}

/* tables at length */
.mockroot .sc-tbl{width:100%;border-collapse:collapse;font-size:13px}
/* Column headers, the same call as `.tb .h`: "Way out", "Appears on",
   "Cancels the work?", "Keyboard". Furniture, in the sans. */
.mockroot .sc-tbl th{text-align:left;font:600 12px/1.3 var(--sans);
  color:var(--ink-3);padding:9px 11px;border-bottom:1px solid var(--line)}
.mockroot .sc-tbl td{padding:9px 11px;border-bottom:1px solid var(--line-soft);color:var(--ink-2);
  vertical-align:top;line-height:1.45}
.mockroot .sc-tbl td b{color:var(--ink)}
/* THE CLASS NAME IS A LEFTOVER. The cells it marks hold "18 Aug" and a
   findings count — a date and a number, both of which are the record
   reporting rather than naming, and neither of which anybody reads
   character by character. Sans with tabular figures, so the columns still
   line up; the markup that says `class="mono"` lives in `ds.py` and is not
   this file's to rename. */
.mockroot .sc-tbl td.mono{font-family:var(--sans);font-size:12px;color:var(--ink-3);
  white-space:nowrap;font-variant-numeric:tabular-nums}
.mockroot .sc-tbl kbd{font:500 10.5px/1 var(--mono);border:1px solid var(--line-strong);
  border-radius:3px;padding:2px 5px;color:var(--ink-2);background:var(--surface-2)}
.mockroot .sc-tbl svg{width:12px;height:12px;vertical-align:-2px}
.mockroot .sc-tw{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;
  background:var(--surface)}
/* "218 releases · 2 waived · Aug 2026", above the scroll. Counts and a
   month. */
.mockroot .sc-tcount{padding:10px 13px;border-bottom:1px solid var(--line);
  background:var(--surface-2);font:500 12.5px/1.3 var(--sans);color:var(--ink-2)}
.mockroot .sc-tcount b{color:var(--ink);font-size:13px}
.mockroot .sc-tscroll{max-height:250px;overflow-y:auto}
.mockroot .sc-tbl.sticky thead th{position:sticky;top:0;background:var(--surface);z-index:1;
  box-shadow:inset 0 -1px 0 var(--line)}
/* the tick was inheriting .ico's own box and clipping inside the 15px check */
.mockroot .sc-mi.on .sc-bx svg,.mockroot .sc-mi.on .sc-bx .ico{
  width:11px;height:11px;display:block;color:var(--on-ink);stroke:var(--on-ink);flex:none}
/* an icon sitting INSIDE a sentence stays on the line with it */
.mockroot .sc-tbl td svg{display:inline-block;vertical-align:-2px;margin:0 1px}
.mockroot .sc-bx svg{overflow:visible}

/* ============ THE COLOUR LAW, APPLIED TO THE SYSTEM ITSELF ============
   The reference system was the worst offender, and that is the expensive
   kind: every screen built by copying it inherits the misuse. --flag marks
   a rule that stops a release, the squiggle under the phrase it caught, and
   the count of those. Nothing else. */

/* A FIELD ERROR IS NOT A BLOCKED RELEASE. It is local, immediate and
   self-evident — the field it sits under is the whole context, so it needs
   no colour to be found. Ink and the alert glyph; the border darkens rather
   than changing hue. */
.mockroot .fld .in.bad{border-color:var(--ink);box-shadow:0 0 0 3px var(--surface-3)}
.mockroot .fld .err{color:var(--ink);font-weight:500}
.mockroot .fld .err::before{content:"!";display:inline-grid;place-items:center;
  width:13px;height:13px;border-radius:50%;background:var(--ink);color:var(--surface);
  font:700 9px/1 var(--sans);margin-right:6px;vertical-align:1px}

/* DESTRUCTIVE IS NOT BLOCKING. Deleting a brand and a rule stopping a
   release are both serious and they are not the same fact. Danger already
   reads as danger through the ink ground and the warning glyph on `.b.dan`;
   these two were the only places still borrowing the stop colour. */
.mockroot .pv a.dan{color:var(--ink)}
.mockroot .sc-mi.dan{color:var(--ink)}
.mockroot .pv a.dan::before,.mockroot .sc-mi.dan .sc-mt b::before{content:"⚠ ";
  font-size:10px;opacity:.75}
/* "2 findings" counts findings; only some of them stop anything. The count
   that earns the colour is "2 stop a release", which is drawn separately.
   The rule is pitch.css:690's `.tPiece .pc-top b`; this page draws neither
   `.pc-top` nor `.fcount`, so it no longer carries a copy. */
/* And this one is a note to the reader of this page, not a product state. */
.mockroot .sc-flagnote{color:var(--ink-2)}

/* ================= TEXT ON A WASH, IN BOTH THEMES =================
   mock.css flips every wash under `prefers-color-scheme:dark` — --flag-wash
   goes #FDEBF4 -> #2C0D1E — and the chips painted a hand-picked DARK hex on
   top of it. In a dark theme that is dark on dark, which is what the whole
   set of state chips measured at: "Cleared" 1.96, "Needs a person" 2.14,
   "Stops a release" 2.27.

   A colour used on a token ground has to be a token too, defined for both
   themes, or one of the two is always broken. These are that pair. */
/* TWO TOKENS THIS FILE USED AND NOBODY DECLARED.
   Both were dropped by every browser that read the page, so the `.sc-*` boxes
   had square corners and the seal had no rule across its top.

   --r-md: mock.css names its radii --r-sm 6, --r 10, --r-lg 16. The scale
   section was written in sm/md/lg, so --r-md is the middle step under the
   other spelling. It is an alias, not a fourth radius — .pv, .kvl, .scr, .bn
   and .fpop, which are the same kind of box as .sc-pop and .sc-tw, all take
   --r already.

   --thread: the one gradient, at most once per view (tokens.css:46). Its ends
   are --flag and --beam, so it turns over with the theme the way the seal's
   ground does; the two middle stops hold. That is what makes the deep variant
   recorded at tokens.css:98 and the bright one at src/index.css:142 a single
   declaration here. */
.mockroot{
  --r-md:var(--r);
  --thread:linear-gradient(103deg,var(--flag) 0%,#8a3ffc 38%,#2b6bff 68%,var(--beam) 100%);
}

/* THE INPUT OUTLINE. The measurement and the reasoning are in this file's
   header. --line-strong separates two surfaces; on a control it is the only
   thing drawing the control, and 1.52:1 is not enough to be that. Same hue,
   same saturation, the lightness moved until it clears 3:1 on every ground a
   control here sits on — down in the light theme, up in the dark. */
.mockroot{--line-control:#8B84A0}
@media (prefers-color-scheme:dark){.mockroot{--line-control:#6D6884}}
[data-theme="dark"] .mockroot{--line-control:#6D6884}
[data-theme="light"] .mockroot{--line-control:#8B84A0}

.mockroot{
  --on-flag-wash:#A4004F; --on-judge-wash:#584A75; --on-cleared-wash:#42561F;
  --on-beam-wash:#0B756F; --on-ink:var(--paper); --on-beam:var(--paper);
}
@media (prefers-color-scheme:dark){.mockroot{
  --on-flag-wash:#FF8CC2; --on-judge-wash:#CBB9F3; --on-cleared-wash:#CDF177;
  --on-beam-wash:#6FEFE5;
}}
[data-theme="dark"] .mockroot{
  --on-flag-wash:#FF8CC2; --on-judge-wash:#CBB9F3; --on-cleared-wash:#CDF177;
  --on-beam-wash:#6FEFE5;
}
[data-theme="light"] .mockroot{
  --on-flag-wash:#A4004F; --on-judge-wash:#584A75; --on-cleared-wash:#42561F;
  --on-beam-wash:#0B756F;
}
.mockroot .tg.stop{color:var(--on-flag-wash)}
.mockroot .tg.judge{color:var(--on-judge-wash)}
.mockroot .tg.clear{color:var(--on-cleared-wash)}

/* The last hand-picked hexes. Each was chosen against one theme's ground and
   is unreadable on the other's. */
.mockroot .cmpsr .kbd{color:var(--paper);opacity:.62}
.mockroot .hero-find .rule .src2{color:var(--on-flag-wash)}
.mockroot .cp:not(.on){color:var(--ink-2)}
/* This specimen is deliberately faded — it is the "too long to be a tooltip"
   example. Marked so an audit reads it as intent rather than a defect. */
.mockroot .sc-tip.over{opacity:.45}
.mockroot .sc-tip.over[data-intent]{opacity:.45}

/* ---- text sitting ON --ink, which inverts with the theme ----
   --ink is the ground here, so an accent on it needs its own pair: bright
   when --ink is dark, deep when --ink is light. --beam alone cannot do this
   because it is tuned to sit on paper, not on ink. */
.mockroot{--on-ink-accent:#6FEFE5}
@media (prefers-color-scheme:dark){.mockroot{--on-ink-accent:#0B756F}}
[data-theme="dark"] .mockroot{--on-ink-accent:#0B756F}
[data-theme="light"] .mockroot{--on-ink-accent:#6FEFE5}

.mockroot .ts .u{color:var(--on-ink-accent)}
.mockroot .cp.on,.mockroot .ds-body .cp.on{color:var(--paper)}
/* A COUNT INSIDE A SELECTED CHIP INHERITS THE CHIP.
   The chip flips to an ink ground when it is on; its count kept --ink-2 and
   went dark-on-dark. (An earlier attempt here painted the stepper's numerals
   instead — those sit on paper, and it made them paper-on-paper. Measured,
   reverted, and left written down.) */
.mockroot .cp.on b,.mockroot .cp.on span,.mockroot .cp.on i{color:inherit}

/* The over-long tooltip specimen was drawn at 45% to say "rejected", which
   made the one example about readability unreadable. It reads at full
   strength now and is marked by the label beside it, which is what the label
   was for. */
.mockroot .sc-tip.over{opacity:1;background:var(--surface-3);color:var(--ink-2);
  border:1px dashed var(--line-strong);box-shadow:none}
/* 10px numerals were at --ink-4, which lands at 4.0:1 on white — under AA for
   text this size. */
.mockroot .cp .n{color:var(--ink-2)}
/* The count in a chip was --ink-2 at opacity .7 and this rule was the patch
   for it. The base rule declares `--ink-3` outright now, so a second copy of
   the same value here would only be a place for the two to drift apart. The
   history stays with the declaration it belongs to. */

/* ===================== 21 · PAGINATION =====================
   pg- prefixed: mock.css owns .page and .nav. Every colour here is a token
   so the set survives the dark theme, which is how the last batch broke. */
.mockroot .pg{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:11px 0;font-size:13px;color:var(--ink-2)}
.mockroot .pg.inset{padding:10px 13px;border-top:1px solid var(--line);
  background:var(--surface-2)}
.mockroot .pg-say{color:var(--ink-2)}
.mockroot .pg-say b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.mockroot .pg-nav{display:flex;align-items:center;gap:3px;margin-left:auto}
.mockroot .pg-n,.mockroot .pg-b{min-width:29px;height:29px;padding:0 7px;border-radius:var(--r-sm);
  display:inline-grid;place-items:center;font-size:13px;color:var(--ink-2);
  border:1px solid transparent;cursor:pointer;font-variant-numeric:tabular-nums}
.mockroot .pg-n:hover,.mockroot .pg-b:hover{background:var(--surface-3);color:var(--ink)}
.mockroot .pg-n.on{background:var(--ink);color:var(--paper);font-weight:600}
.mockroot .pg-b{border-color:var(--line-strong)}
/* a control that cannot act says so by being flat, never by fading — opacity
   is what put the disabled buttons at 1.75:1 earlier in this file */
.mockroot .pg-b.off{color:var(--ink-4);border-color:var(--line);cursor:not-allowed;
  background:var(--surface-3)}
.mockroot .pg-b.off:hover{background:var(--surface-3);color:var(--ink-4)}
.mockroot .pg-b svg{width:13px;height:13px}
.mockroot .pg-el{padding:0 3px;color:var(--ink-3)}
.mockroot .pg-size{display:inline-flex;align-items:center;gap:5px;padding:5px 9px;
  border:1px solid var(--line-strong);border-radius:var(--r-sm);cursor:pointer;
  color:var(--ink-2);font-size:12.5px}
.mockroot .pg-size b{color:var(--ink);font-weight:600}
.mockroot .pg-size svg{width:11px;height:11px}
/* A CEILING IS NOT A FOOTNOTE. A governance record that silently drops rows
   is worse than one that refuses, so the warning sits inside the count. */
.mockroot .pg-warn{display:inline-flex;align-items:center;gap:5px;margin-left:9px;
  padding:3px 8px;border-radius:99px;background:var(--judge-wash);
  color:var(--on-judge-wash);font:500 11.5px/1.4 var(--sans)}
.mockroot .pg-warn svg{width:12px;height:12px}
/* "Reading page 2…" — a sentence about what is happening, set like the
   `.pg-warn` beside it rather than like a serial number. */
.mockroot .pg-busy{font:500 11.5px/1.4 var(--sans);color:var(--ink-3)}
.mockroot .pg.busy .pg-say b{color:var(--ink-3)}
.mockroot .pg-empty{padding:26px 0 8px;display:flex;flex-direction:column;gap:6px;max-width:62ch}
.mockroot .pg-empty b{font-size:15px;color:var(--ink);font-weight:600}
.mockroot .pg-empty span{font-size:13.5px;line-height:1.55;color:var(--ink-2)}
/*
 * THE PRE-AUTH BOARDS' STYLESHEET.
 *
 * Source: `docs/superpowers/mockups/preauth.css`, copied 21 Aug 2026.
 * Generator: `docs/superpowers/mockups/preauth.py`, which splices
 * `src/design/mock.css`, then `ds.css`, then this file. The board page's own
 * furniture (`.ds`, `.ds-w`, `.ds-card`) comes from `ds.css`; the app does not
 * draw those.
 *
 * Copied whole for the reason `ds.css`, `pitch.css` and `mock.css` are copied
 * whole: deciding which half to take is what has gone wrong every previous
 * time. See `ds.css`'s header.
 *
 * ---------------------------------------------------------------------------
 * WHAT IS SAFE TO LOAD GLOBALLY, AND WHY THIS FILE IS
 * ---------------------------------------------------------------------------
 *
 * `pitch.css` had to be scoped to `.ppboard` because it names forty short
 * generic things — `.body`, `.chip`, `.st`, `.m`. This one names nothing
 * generic. Every selector is either `pa-` prefixed or scoped to `.ds-body`,
 * which is the design catalogue's card body and exists on no product route, so
 * there is nothing here for an unported screen to collide with. It is loaded by
 * `src/auth/Preauth.tsx` — the three screens with no signed-in shell — rather
 * than by `Shell.tsx`, because those screens are the ones outside it.
 *
 * If any of it is wrong it is wrong in `preauth.py`. Do not edit this file to
 * fix a screen.
 */
/* ===========================================================================
   THE THREE SCREENS WITH NO SIGNED-IN SHELL — 20 Aug 2026
   Spliced after src/design/mock.css and ds.css, both unmodified. Additive:
   every control on these boards is ds.css's, and what is below is the
   arrangement those controls sit in — a setup chrome, an auth column, a
   review page. No new colour, typeface or radius; every value here is a
   mock.css token or a measurement.

   One rule held throughout: a colour that lands on a token ground is a token
   too. ds.css:570-584 already pairs the four washes with readable text for
   both themes (--on-flag-wash and friends), so nothing here re-picks a hex
   against one theme's paper.
   =========================================================================== */

/* --------------------------------------------------------- board scaffold --
   ds.css gives .ds / .ds-w / .ds-h / .ds-card / .ds-t / .ds-body. These are
   the two arrangements it does not have: a pair that collapses on a phone,
   and a caption under a specimen. .ds-grid2 is left alone — it belongs to
   the other board and holds two columns at every width by design. */
.pa-two{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:start}
.pa-three{display:grid;grid-template-columns:1fr 1fr 1fr;gap:18px;align-items:start}
@media (max-width:900px){.pa-two,.pa-three{grid-template-columns:1fr}}
/* A caption is a sentence — "Costs nothing to build. Five tabs still say 'you
   already know this product'." It was uppercase mono at 10px with .1em of
   tracking, which is the treatment an identifier gets, and it was under the
   10.5px type floor `accessibility.test.tsx:491` holds the product to. Sans,
   sentence case, 12: the same words, read rather than spelled. */
.pa-cap{font-family:var(--sans);font-size:12px;color:var(--ink-3);margin:10px 0 0}
.pa-stack>*+*{margin-top:16px}
/* mock.css gives .ico display:block, so ds.css's centred empty state puts its
   glyph against the left edge. Centred here rather than in ds.css. */
.ds-body .stt>.ico{margin-left:auto;margin-right:auto}
/* ds.css's modal is a fixed 440 inside a .scr that clips, so on a phone-width
   board it loses its left edge and both its buttons. The specimen is the whole
   point of the card, so it is fitted to the frame at narrow widths rather than
   left half-drawn. */
@media (max-width:560px){
  .ds-body .md{width:auto;left:10px;right:10px;transform:translateY(-50%)}
  .ds-body .md .ft{flex-wrap:wrap}
}
/* A banner's action is a control, not a paragraph — ds.css's .bn is a flex row
   and lets the button shrink to three words on three lines. */
.ds-body .bn>.b{flex:none;white-space:nowrap}
@media (max-width:640px){.ds-body .bn{flex-wrap:wrap}.ds-body .bn>.b{margin-left:0!important}}

/* A phone, drawn at its real width so the cost of a control is visible
   rather than argued about. 390 is the iPhone 15 logical width and the one
   the review link is opened on. */
.pa-ph{width:390px;max-width:100%;border:1px solid var(--line-strong);border-radius:var(--r-lg);
       overflow:hidden;background:var(--paper);box-shadow:var(--shadow-2)}
.pa-phs{display:flex;gap:22px;flex-wrap:wrap;align-items:flex-start}
.pa-phbody{padding:16px 14px 0}

/* ------------------------------------------------------------ setup chrome --
   FORK B. The wizard renders inside AppShell today (FirstRun.tsx:80-100) with
   five tabs that lead nowhere for a new account. The recorded objection to
   moving it out is that AppShell sets .mockroot and the stylesheet is scoped
   to it — which this answers by putting the class here instead. The chrome
   holds three things and no more: whose product this is, how many asks are
   left, and the way out that Onboarding #14 has never had. */
.pa-chrome{display:flex;align-items:center;gap:14px;padding:13px 20px;
           border-bottom:1px solid var(--line);background:var(--surface)}
/* The wordmark WAS set in type here. It is a picture now — see PRE-AUTH MARK. */
/* "2 left · Leave setup" on the wizard, "Privacy · Terms" on the auth pages.
   A count and two links, which is chrome copy: sans, sentence case, and none
   of the tracking that was there to keep uppercase mono apart. */
.pa-chrome .pa-left{margin-left:auto;font-family:var(--sans);font-size:12.5px;
                    color:var(--ink-3)}

/* FORK A, for comparison: the shell stays and the dead tabs are dimmed.
   Dimmed with a COLOUR — --ink-4 is the token that clears 4.5:1 on every
   ground mock.css puts it on (mock.css's own note) — never with opacity,
   which would take the ground down with the label. */
.pa-tabs{display:flex;align-items:center;gap:20px;padding:13px 20px;
         border-bottom:1px solid var(--line);background:var(--surface);font-size:13.5px}
.pa-tabs a{color:var(--ink-4)}
.pa-tabs a.on{color:var(--ink);font-weight:600}

/* ------------------------------------------------------------ the wizard --
   A column, not a card. mock.css already has .page/.pagehead/.eyebrow and
   ds.css redefines .page for its own board, so the wizard's frame is named
   here rather than inherited from whichever file happens to load last. */
.pa-page{padding:26px 28px 30px;background:var(--paper)}
.pa-head{display:flex;gap:20px;align-items:flex-start;
         border-bottom:1px solid var(--line);padding-bottom:18px;margin-bottom:20px}
/* "Setting up · <the domain you gave>", "Already set up · <brand>". An eyebrow
   names where you are; it is not an identifier, so it is sans and sentence
   case at the chrome size rather than spelled out in caps at 10.
   The example domain that stood here was lifted from the first-run rig, and
   `firstRunRig.test.ts` caught it in the shipped CSS bundle — comments in this
   file are published, so a fixture string in one is a fixture string on the
   wire. Shapes, never the rig's own words. */
.pa-eyebrow{display:flex;align-items:center;gap:8px;font-family:var(--sans);font-size:12.5px;
            color:var(--ink-3);margin:0 0 9px}
.pa-h{font-size:25px;line-height:1.18;letter-spacing:-.022em;margin:0;font-weight:600;color:var(--ink)}
.pa-lede{font-size:14px;line-height:1.6;color:var(--ink-2);margin:9px 0 0;max-width:56ch}
/* How many asks are left, beside the heading. A count, not a revision. */
.pa-count{margin-left:auto;font-family:var(--sans);font-size:12.5px;
          color:var(--ink-3);white-space:nowrap;padding-top:3px}
.pa-form{max-width:52ch}
/* ds.css declares .fld on an inline span, so a margin on one does nothing and
   a stack of three fields runs its hint text into the next field's label.
   Blocked here rather than in ds.css, which is spliced unmodified. */
.pa-page .fld,.pa-panel .fld,.pa-auth .fld{display:block}
.pa-page .fld+.fld,.pa-panel .fld+.fld{margin-top:20px}
/* THE NAME IS NOW HISTORICAL — this is the wizard's quiet paragraph and it is
   set in the sans. It carries whole sentences: "Nothing here is saved yet.
   What stays ticked lands with the brand when it is created." Mono was making
   the calmest copy on the screen the loudest thing on it. The one line that
   does hold an identifier prints the fingerprint inside a sentence, and a
   sentence is not an identifier because it contains one. Renaming the class
   means editing four screens; it is a name, not a face. */
.pa-mono{font-family:var(--sans);font-size:12.5px;line-height:1.6;
         color:var(--ink-3);margin:9px 0 0}
.pa-acts{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:20px}

/* The site-read card. Each row falls alone, which is the whole of it. */
.pa-rows{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--surface)}
.pa-row{display:flex;gap:12px;align-items:flex-start;padding:13px 15px;
        border-bottom:1px solid var(--line-soft);font-size:13.5px}
.pa-row:last-child{border-bottom:0}
/* Why the row is ticked, in words: "Taken from the stylesheet, ranked by
   area", "Loaded on every page · closest pairing we ship". A reason is prose.
   9.5px uppercase mono was also under the 10.5 floor. */
.pa-row .pa-why{display:block;font-family:var(--sans);font-size:12px;
                color:var(--ink-3);margin-top:5px}
.pa-sw{width:15px;height:15px;border-radius:3px;display:inline-block;vertical-align:-2px;
       box-shadow:inset 0 0 0 1px rgba(23,21,28,.16);margin-right:5px}

/* The catch. The words, the rule that caught them, what ran. ds.css's
   .hero-find is the same object at hero size; this is its wizard-sized
   sibling, and it borrows the squiggle rather than redrawing it. */
.pa-catch{border:1px solid var(--line-strong);border-radius:var(--r-lg);overflow:hidden;
          background:var(--surface);box-shadow:var(--shadow-2)}
.pa-quote{padding:22px 24px;font-family:var(--serif);font-size:19px;line-height:1.62;color:var(--ink)}
.pa-said{padding:0 24px 18px;font-family:var(--serif);font-size:14.5px;line-height:1.5;
         color:var(--ink-2);margin:0}
/* Which rule caught it and on what: "Halvard house rules — already yours ·
   matched 'completely safe'". A rule's name and the words it matched are the
   sentence under the quote, so they read as one. */
.pa-src{padding:0 24px 16px;font-family:var(--sans);font-size:12px;
        color:var(--ink-3);display:block}
.pa-ratio{padding:14px 24px;border-top:1px solid var(--line);background:var(--surface-2)}
/* Settled in code, needs a person, and the rest. --cleared and --judge carry
   exactly what they mean; the remainder is a line, not a third colour. */
.pa-bar{height:6px;border-radius:99px;background:var(--surface-3);display:flex;overflow:hidden}
.pa-bar i{display:block;height:100%}
.pa-bar i.ok{background:var(--cleared)}
.pa-bar i.jd{background:var(--judge)}

/* The receipt. One rule per row, all of them, by their own words. */
.pa-rules{border-top:1px solid var(--line)}
.pa-rulerow{display:flex;gap:14px;align-items:flex-start;padding:13px 0;
            border-bottom:1px solid var(--line-soft);font-size:14px;line-height:1.5}
.pa-rulerow q{quotes:none;font-family:var(--serif);font-size:14.5px;line-height:1.5;color:var(--ink)}
/* A rule's severity on the receipt, in ink. Nothing has been checked yet, so
   there is no finding here for --flag to mean. "Stops a release", "Warns
   only", "Stood down" — state words, so sans and sentence case; the 112px
   column holds all three at 12.5. */
.pa-sev{flex:none;width:112px;font-family:var(--sans);font-size:12.5px;
        color:var(--ink-2);padding-top:3px}
@media (max-width:560px){.pa-rulerow{flex-direction:column;gap:6px}.pa-sev{width:auto;padding:0}}
/* Where the rule came from — "ABPI code of practice · 4.2", or the reason it
   is stood down. A sentence with a locator in it, not a locator. */
.pa-rulerow .pa-why{display:block;font-family:var(--sans);font-size:12px;
                    color:var(--ink-3);margin-top:5px}

/* -------------------------------------------------------------- sign-in ---
   One column at 420, which is what /login already is. /signup is the same
   column inside the full marketing nav and a seven-column footer; on the
   board they are one chrome, because they are one act with two doors. */
.pa-auth{max-width:420px;margin:0 auto;padding:34px 24px 40px}
.pa-authh{font-size:27px;letter-spacing:-.028em;line-height:1.1;margin:0;font-weight:700;color:var(--ink)}
.pa-authp{font-size:14px;line-height:1.6;color:var(--ink-2);margin:12px 0 0}
.pa-authq{font-size:13px;line-height:1.6;color:var(--ink-3);margin:10px 0 0}
.pa-prov{display:flex;flex-direction:column;gap:10px;margin-top:24px}
.pa-prov .b{justify-content:center;width:100%}
.pa-or{display:flex;align-items:center;gap:12px;margin:22px 0}
.pa-or i{height:1px;flex:1;background:var(--line)}
/* One word between two hairlines. It says "or", so it reads "or" — not "O R"
   in a face reserved for things you have to spell out. */
.pa-or span{font-family:var(--sans);font-size:12px;color:var(--ink-3)}
.pa-foot{font-size:13px;color:var(--ink-3);margin-top:22px;line-height:1.7}
/* THE LINK IS NOT A FINDING. /login paints "Start free" in --flag today
   (Login.tsx:291). --beam is the token for emphasis that is not an alarm. */
.pa-foot a,.pa-link{color:var(--beam);text-decoration:underline;text-underline-offset:3px}

/* ------------------------------------------------------- external review ---
   No shell to sit in and no tabs to sit under, so the page carries its own
   identification: whose work this is, above everything else. */
.pa-rv{padding:24px 26px 30px;background:var(--paper)}
.pa-brand{display:flex;align-items:center;gap:11px;margin-bottom:14px}
/* #fff, and it is not a theme token because the ground under it is not one
   either: the square is the customer's own accent, carried in the share
   payload, and it does not flip with our palette. pitch.py paints the frame
   footers the same way for the same reason. */
.pa-mark{width:30px;height:30px;border-radius:7px;display:grid;place-items:center;flex:none;
         font-family:var(--sans);font-weight:800;font-size:14px;color:#fff}
.pa-brand b{display:block;font-size:14px;font-weight:600;color:var(--ink)}
/* The access this link carries, under the brand's name: "Q3 access". */
.pa-brand span{display:block;font-family:var(--sans);font-size:12px;
               color:var(--ink-3);margin-top:2px}
.pa-title{font-size:29px;line-height:1.13;letter-spacing:-.026em;margin:0;font-weight:600;color:var(--ink)}
.pa-ask{font-size:14.5px;line-height:1.6;color:var(--ink-2);margin:12px 0 0;max-width:62ch}
/* The facts about the link, as marks. Access is the one thing that changes
   what a reviewer can do, so it is the one carrying colour. They are
   sentences — "No account needed", "Sent to Jane Okafor", "Expires
   04/09/2026" — so they are sans, sentence case, at the chrome size. */
.pa-facts{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;margin-top:16px}
.pa-facts .m{font-family:var(--sans);font-size:12.5px;color:var(--ink-3)}
.pa-rvgrid{display:grid;grid-template-columns:minmax(0,400px) minmax(0,1fr);gap:34px;
           align-items:start;margin-top:22px}
@media (max-width:900px){.pa-rvgrid{grid-template-columns:1fr;gap:24px}}
/* The frame strip is the navigation and the progress in one object. Dashed
   until opened; --beam on the one on screen, which is what it means in the
   editor already. */
.pa-fstrip{display:flex;gap:7px;flex-wrap:wrap;align-items:center;margin-top:6px}
/* One digit, centred in a box by the grid rather than by the figure's width,
   and the badge on its corner is a comment count. Neither is something a
   person spells out, so neither is mono; `tabular-nums` keeps the strip even
   once a deck runs past nine frames. */
.pa-fc{width:34px;height:34px;border-radius:var(--r-sm);display:grid;place-items:center;
       font-family:var(--sans);font-size:12.5px;font-variant-numeric:tabular-nums;
       color:var(--ink-3);background:var(--surface);
       border:1px dashed var(--line-strong);position:relative}
.pa-fc.seen{border-style:solid;color:var(--ink-2)}
.pa-fc.on{border-color:var(--beam);border-style:solid;color:var(--ink);font-weight:600;
          box-shadow:0 0 0 2px var(--beam-wash)}
.pa-fc b{position:absolute;top:-5px;right:-5px;min-width:15px;height:15px;border-radius:99px;
         background:var(--ink);color:var(--paper);font-size:9px;display:grid;place-items:center;
         font-weight:600}
/* A frame, at 4:5, capped so a desktop reviewer takes it in whole. */
.pa-frame{aspect-ratio:4/5;border-radius:var(--r);overflow:hidden;display:flex;
          flex-direction:column;justify-content:flex-end;padding:22px;margin-top:12px;color:#fff}
.pa-frame p{margin:0;font-family:var(--serif);font-size:20px;line-height:1.34}
/* The strap across the foot of a frame: "Northwind Dermatology · 02/05". A
   brand's name and where you are in the deck — metadata, in the sans. The
   board's own artwork strap (`pitch.css` `.art-f .ix`) is a bare 01/05 and
   keeps its mono; this one carries words. */
.pa-frame .ix{font-family:var(--sans);font-size:11px;margin-top:14px;display:block}
/* WHAT WAS CHECKED — four counts, drawn even when three of them are zero,
   because an empty findings array is not compliance. The figure is the big
   thing; what it counts — "Stop a release", "Need a person", "Settled in
   code", "Not checked" — is a phrase and reads as one, in the sans at 12. It
   was 9px uppercase mono, four points under the type floor. */
.pa-counts{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
           border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-top:16px}
.pa-counts div{background:var(--surface);padding:12px 13px}
.pa-counts b{display:block;font-size:20px;font-weight:600;color:var(--ink);line-height:1}
.pa-counts span{display:block;font-family:var(--sans);font-size:12px;
                color:var(--ink-3);margin-top:6px;line-height:1.4}
@media (max-width:560px){.pa-counts{grid-template-columns:1fr 1fr}}

/* A panel — the identity ask, the thread, the sign-off. */
.pa-panel{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);
          padding:18px 20px}
/* What the panel below is about: "On frame 2", "On the whole post". */
.pa-lbl{font-family:var(--sans);font-size:12.5px;
        color:var(--ink-3);margin:0 0 10px;display:block}

/* Comments. A remark carries the fingerprint of what its writer was looking
   at (share/types.ts:59) and the thread has never read it — so a comment
   written against words that have since changed looks exactly like one
   written against these. Colour carries it, because colour is what gets read,
   and --judge is the right one: a stale remark is not a finding, it is a
   thing a person has to weigh. */
.pa-cmt{border:1px solid var(--line);border-left-width:3px;border-radius:var(--r-sm);
        padding:11px 13px;background:var(--surface)}
.pa-cmt+.pa-cmt{margin-top:9px}
.pa-cmt .who{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pa-cmt .who b{font-size:13.5px;font-weight:600;color:var(--ink)}
/* Who they are and when they said it — "Group Compliance · 19/08". A role and
   a date, beside a name that is already sans. */
.pa-cmt .who .m{font-family:var(--sans);font-size:12px;color:var(--ink-3)}
.pa-cmt p{margin:7px 0 0;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
.pa-cmt.stale{border-left-color:var(--judge);background:var(--judge-wash)}
.pa-cmt.stale .note{display:block;margin-top:8px;font-size:12.5px;line-height:1.5;
                    color:var(--on-judge-wash)}
/* RESOLVED IS A COLOUR. It was opacity:.6 (ReviewPage.tsx:336), which fades
   the author's name and the ground at the same rate and takes a compliance
   record's attribution with it. */
.pa-cmt.done{border-left-color:var(--cleared);background:var(--cleared-wash)}
.pa-cmt.done p{color:var(--ink-2)}

/* The meter above the attestation. It gates nothing — this page cannot know
   who is holding the phone — it just puts the count in front of the person
   about to claim they read every frame. "3 of 5 frames opened" is that
   sentence, so it is set like one. */
.pa-meter{display:flex;align-items:center;gap:11px;margin-top:14px}
.pa-meter i{flex:1;height:6px;border-radius:99px;background:var(--surface-3);display:block;
            overflow:hidden}
.pa-meter i u{display:block;height:100%;background:var(--beam)}
.pa-meter i.full u{background:var(--cleared)}
.pa-meter span{font-family:var(--sans);font-size:12.5px;color:var(--ink-3)}

/* An earlier sign-off, and whether it still covers these words.
   --judge, and this is a deliberate departure from what ships. ReviewPage
   draws a lapsed sign-off with border-flag (ReviewPage.tsx:1697-1707) and its
   reasoning — that colour is what gets read — is right; the colour is wrong.
   The law reserves --flag for a finding that stops a release, its squiggle and
   the count of those, and names a waiver and a date among the things it is
   never for. An approval that no longer covers the words on screen is not a
   finding; it is the definition of a thing a person must decide about, which
   is --judge. The mark, the ground and the sentence all change either way, so
   nothing is lost by taking the magenta back. */
.pa-so{border:1px solid var(--cleared);border-radius:var(--r-sm);padding:11px 13px;
       background:var(--surface)}
.pa-so+.pa-so{margin-top:9px}
.pa-so b{font-size:13.5px;font-weight:600;color:var(--ink)}
.pa-so p{margin:6px 0 0;font-size:12.5px;line-height:1.5;color:var(--ink-3)}
.pa-so q{quotes:none;display:block;margin-top:7px;font-family:var(--serif);font-size:13.5px;
         line-height:1.5;color:var(--ink-2)}
.pa-so.lapsed{border-color:var(--judge);background:var(--judge-wash)}
.pa-so.lapsed p{color:var(--on-judge-wash)}
/* The attestation itself, with the counts inside the sentence being ticked. */
.pa-att{display:flex;gap:11px;align-items:flex-start;margin-top:14px;font-size:13.5px;
        line-height:1.6;color:var(--ink)}
.pa-tick{width:17px;height:17px;border-radius:4px;border:1.5px solid var(--line-strong);flex:none;
         margin-top:2px;background:var(--surface);display:block}
.pa-tick.on{background:var(--ink);border-color:var(--ink);position:relative}
.pa-tick.on::after{content:'';position:absolute;left:5px;top:1px;width:5px;height:9px;
                   border:solid var(--paper);border-width:0 2px 2px 0;transform:rotate(45deg)}

/* The bar that stays with the viewport on a phone. A card, not a full-bleed
   strip, so it reads as a control rather than as browser chrome. */
.pa-sticky{position:sticky;bottom:0;margin:18px -14px 0;padding:10px 14px 14px}
.pa-stickyc{display:flex;align-items:center;gap:9px;background:var(--surface);
            border:1px solid var(--line-strong);border-radius:var(--r-lg);padding:8px 10px;
            box-shadow:var(--shadow-3)}
/* "Frame 2 of 5", between the two arrows. Where you are, not which one. */
.pa-stickyc .m{font-family:var(--sans);font-size:12.5px;color:var(--ink-3);margin:0 4px}

/* A dead link. NOT --flag: a withdrawn link and a mistyped address are not
   findings that stop a release. The brand line stays, so a cold arrival can
   still tell whose link they are holding. */
.pa-dead{border:1px solid var(--line-strong);border-radius:var(--r-lg);background:var(--surface);
         padding:26px 24px;max-width:460px}
.pa-dead h5{margin:12px 0 6px;font-size:16px;font-weight:600;color:var(--ink)}
.pa-dead p{margin:0 0 16px;font-size:13.5px;line-height:1.55;color:var(--ink-2)}

/* ---------- PRE-AUTH MARK ------------------------------------------------
   At the foot for the same reason `pitch.css` puts its masthead mark here:
   `src/review/ReviewPage.tsx` cites `preauth.css:219` and `:289`, that file
   belongs to another contract, and this rule set is 21 lines longer than the
   one line of type it replaces. Appended, nothing above it moves. */
/* Was INKSTAND set in the sans at 13/800 with .14em of tracking — a logotype
   spelled out because there was no mark. There is one now. It is drawn 20px
   tall, which puts its LETTERS at 13.4px: the mark's own type occupies the top
   67% of the file, so 20 is the height at which it reads the same size as the
   13px it replaces rather than shrinking the chrome's one piece of identity.
   Width 54.4 = 313/115 x 20.

   `line-height:0` because an inline image sits on the text baseline and brings
   the descender space under it along, which pushed the 14px gap to the two
   links out of true.

   The picture, the dark swap and the two custom properties work exactly as
   pitch.css's `.sh-m` does, and the long note is there: one element rather than
   two so the link's accessible name is "Inkstand" once, `content` rather than a
   display toggle, and `--pa-wm-*` behind it so `preauth.py` can point the board
   at data URIs it can open over file://. */
.pa-wm{display:inline-flex;align-items:center;line-height:0;
       --pa-wm-l:url(/brand/inkstand-wordmark.png);
       --pa-wm-d:url(/brand/inkstand-wordmark-dark.png)}
.pa-wm img{height:20px;width:54.4px;display:block;object-fit:contain;content:var(--pa-wm-l)}
@media (prefers-color-scheme:dark){.pa-wm img{content:var(--pa-wm-d)}}
[data-theme="dark"] .pa-wm img{content:var(--pa-wm-d)}
[data-theme="light"] .pa-wm img{content:var(--pa-wm-l)}
.lifecycle-preview{min-height:100vh;background:#ece9e2;color:#201f1b;font-family:'Switzer',system-ui,sans-serif;padding:clamp(24px,5vw,72px) clamp(18px,5vw,80px) 56px}.lifecycle-preview *{box-sizing:border-box}.lifecycle-hero,.lifecycle-principle,.lifecycle-index,.lifecycle-emails,.lifecycle-footer{max-width:1340px;margin:0 auto}.lifecycle-hero{border-bottom:1px solid #bdb9ae;padding-bottom:36px}.lifecycle-hero__eyebrow,.lifecycle-message__category,.lifecycle-message__number,.send-contract dt,.send-contract__title,.email-paper__footer,.mail-client__chrome,.lifecycle-footer span{font-family:'SF Mono',ui-monospace,monospace;font-size:10px;letter-spacing:.08em;text-transform:uppercase}.lifecycle-hero__eyebrow{display:flex;align-items:center;gap:8px;color:#67645c}.lifecycle-hero__dot{display:block;width:7px;height:7px;border-radius:50%;background:#618d81}.lifecycle-hero__heading{display:flex;justify-content:space-between;align-items:end;gap:40px;margin-top:46px}.lifecycle-hero h1{font-family:Charter,Georgia,serif;font-size:clamp(48px,7vw,98px);font-weight:400;line-height:.9;letter-spacing:-.055em;margin:0}.lifecycle-hero p{max-width:600px;margin:18px 0 0;font-size:17px;line-height:1.5;color:#57554e}.lifecycle-guard{border-left:2px solid #8e7ab6;max-width:340px;padding:8px 0 8px 15px}.lifecycle-guard span{display:block;color:#716d65;font-size:11px;font-weight:600}.lifecycle-guard strong{display:block;margin-top:7px;font-size:13px;line-height:1.45;font-weight:500}.lifecycle-principle{padding:16px 0;border-bottom:1px solid #bdb9ae}.lifecycle-principle p{display:flex;gap:28px;flex-wrap:wrap;margin:0;color:#4e4c45;font-size:13px}.lifecycle-principle span::before{content:'—';margin-right:7px;color:#767168}.lifecycle-index{display:flex;gap:20px;overflow:auto;padding:19px 0;border-bottom:1px solid #bdb9ae}.lifecycle-index a{color:#555149;text-decoration:none;font-family:'SF Mono',ui-monospace,monospace;font-size:10px;letter-spacing:.04em;white-space:nowrap}.lifecycle-index a span{color:#9b3e69;margin-right:6px}.lifecycle-emails{padding-top:24px}.lifecycle-message{padding:70px 0;border-bottom:1px solid #bdb9ae;scroll-margin-top:16px}.lifecycle-message__header{display:grid;grid-template-columns:56px minmax(0,1fr) 280px;gap:18px;align-items:start;margin-bottom:26px}.lifecycle-message__number{color:#9b3e69;padding-top:4px}.lifecycle-message__category{margin:0 0 8px;color:#69645b}.lifecycle-message h2{font-family:Charter,Georgia,serif;font-size:clamp(30px,4vw,48px);font-weight:400;letter-spacing:-.035em;line-height:1.02;margin:0}.lifecycle-message__intent{border-left:1px solid #bdb9ae;padding-left:15px;margin-top:5px}.lifecycle-message__intent span{font-family:'SF Mono',ui-monospace,monospace;text-transform:uppercase;letter-spacing:.08em;font-size:9px;color:#716d65}.lifecycle-message__intent p{margin:6px 0 0;color:#57554e;font-size:13px;line-height:1.45}.lifecycle-message__content{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:24px;align-items:start}.mail-client{background:#f8f7f3;border:1px solid #bdb9ae;box-shadow:7px 8px 0 rgba(69,66,58,.12)}.mail-client__chrome{height:35px;padding:0 12px;display:flex;align-items:center;gap:12px;background:#dedbd3;color:#656159}.mail-client__traffic{display:flex;gap:4px}.mail-client__traffic i{display:block;width:7px;height:7px;border-radius:50%;background:#a6a197}.mail-client__mode{margin-left:auto}.mail-client__meta{padding:16px 22px 14px;display:flex;align-items:center;gap:10px;border-bottom:1px solid #dedbd3}.mail-client__meta strong,.mail-client__meta span{display:block;font-size:12px}.mail-client__meta span{margin-top:2px;color:#6f6a60;font-size:11px}.mail-client__meta time{margin-left:auto;color:#6f6a60;font-family:'SF Mono',ui-monospace,monospace;font-size:10px}.lifecycle-mark{display:block;width:20px;height:20px;flex:none;border-radius:3px;position:relative;background:#5d8f83}.lifecycle-mark::after{content:'';position:absolute;width:7px;height:7px;border-radius:50%;background:#f8f7f3;top:3px;right:3px}.lifecycle-mark--violet{background:#8975ab}.lifecycle-mark--lime{background:#82973c}.lifecycle-mark--rose{background:#ab4d6b}.mail-client__subject{padding:15px 22px 13px;border-bottom:1px solid #dedbd3;font-size:16px;font-weight:600}.email-paper{max-width:640px;margin:0 auto;background:#fffdf9}.email-paper__header{padding:26px 34px 20px;border-bottom:1px solid #e6e1d8}.email-paper__brand{display:flex;align-items:center;gap:8px;font-family:Charter,Georgia,serif;font-size:20px;font-weight:600;letter-spacing:-.04em}.email-paper__brand .lifecycle-mark{width:15px;height:15px}.email-paper__brand .lifecycle-mark::after{width:5px;height:5px;top:2px;right:2px}.email-paper__preheader{display:block;margin-top:21px;color:#716d65;font-size:11px}.email-paper__body{padding:30px 34px 38px;font-size:15px;line-height:1.6}.email-paper__body p{margin:0 0 17px}.email-paper__cta{display:inline-block;margin:8px 0 0;background:#24231f;color:#fffdf9;text-decoration:none;padding:10px 14px;font-size:13px;font-weight:600}.email-paper__footnote{margin-top:23px!important;border-top:1px solid #e6e1d8;padding-top:15px;color:#686359;font-size:12px}.email-paper__footer{display:flex;justify-content:space-between;gap:12px;padding:13px 34px;border-top:1px solid #e6e1d8;color:#777168;font-size:8px}.email-decisions{display:grid;gap:10px;margin:22px 0 16px;padding:0;list-style:none;counter-reset:decision}.email-decisions li{counter-increment:decision;border-left:2px solid #82973c;padding:6px 10px 7px 14px}.email-decisions li::before{content:'0' counter(decision);font-family:'SF Mono',ui-monospace,monospace;font-size:9px;color:#698030;display:block;margin-bottom:3px}.email-decisions strong{display:block;font-size:13px;line-height:1.35}.email-decisions span{display:block;margin-top:4px;color:#706b62;font-size:11px;line-height:1.4}.send-contract{background:#e3e0d7;border:1px solid #bdb9ae;padding:16px}.send-contract__title{display:flex;justify-content:space-between;align-items:center;padding-bottom:13px;border-bottom:1px solid #c6c1b6;color:#4f4b43}.send-contract__status{background:#f7ecef;color:#93435f;padding:4px 6px;font-size:8px;letter-spacing:.05em}.send-contract dl{margin:0}.send-contract dl>div{padding:13px 0;border-bottom:1px solid #cac5bb}.send-contract dl>div:last-child{border:0;padding-bottom:0}.send-contract dt{color:#777168;font-size:8px}.send-contract dd{margin:5px 0 0;font-size:12px;line-height:1.42;color:#34322d}.lifecycle-footer{display:flex;justify-content:space-between;gap:30px;padding:26px 0 0;color:#645f56;font-size:12px;line-height:1.45}.lifecycle-footer p{max-width:680px;margin:0}.lifecycle-footer span{font-size:9px;white-space:nowrap}@media (max-width:800px){.lifecycle-hero__heading,.lifecycle-message__content{display:block}.lifecycle-guard{margin-top:30px}.lifecycle-message{padding:46px 0}.lifecycle-message__header{grid-template-columns:38px minmax(0,1fr)}.lifecycle-message__intent{grid-column:2;margin-top:5px}.send-contract{margin-top:20px}.lifecycle-footer{display:block}.lifecycle-footer span{display:block;margin-top:16px;white-space:normal}.email-paper__header,.email-paper__body{padding-left:22px;padding-right:22px}.email-paper__footer{padding-left:22px;padding-right:22px;display:block}.email-paper__footer span+span{display:block;margin-top:5px}}
/*
 * The printed copy.
 *
 * Procurement does not read a legal document in a browser. It saves it, renames
 * it, and attaches it to a file that will be opened again in two years by
 * somebody who was not part of the conversation. So the printed artefact is the
 * real deliverable and the screen is the preview, which is the opposite of how
 * a marketing page is usually built.
 *
 * A print stylesheet rather than a PDF pipeline: the browser already lays out,
 * paginates, hyphenates and produces a PDF, and every one of those is a place a
 * generator would have to be maintained. What it cannot do on its own is turn a
 * near-black interface into something that will not empty a toner cartridge, so
 * that is all this file does.
 *
 * Unlayered on purpose. Tailwind v4 puts its utilities in a cascade layer, and
 * unlayered rules beat layered ones outright, so nothing here needs !important
 * to defeat a utility class — only to defeat inline styles, which is why the
 * two rules that do carry it are the two that override a style attribute.
 *
 * Scoped through :has([data-legal-doc]) so that printing any other page on the
 * site is untouched by it.
 */

@media print {
  @page {
    margin: 18mm 16mm 20mm;
  }

  /* The dark chrome inverts wholesale. The shell is three nested elements deep
     — body, #root, the layout div — and the near-black is painted on the last
     of them, so whitening the body alone leaves the page black. */
  body:has([data-legal-doc]),
  body:has([data-legal-doc]) #root,
  body:has([data-legal-doc]) #root > div,
  body:has([data-legal-doc]) main {
    background: #fff;
    color: #111;
  }

  /* Navigation, the print button, the anchor affordances, the skip link. None
     of it means anything on paper and all of it costs a line. <header> and
     <footer> appear nowhere else in this tree, so the plain descendant
     selectors cannot reach anything inside a document. */
  body:has([data-legal-doc]) header,
  body:has([data-legal-doc]) footer,
  body:has([data-legal-doc]) [data-print-hide] {
    display: none !important;
  }

  [data-print-only] {
    display: block !important;
  }

  [data-legal-doc] {
    background: #fff;
  }

  /* The measure on screen is set by a grid that assumes a 1180px viewport; on
     A4 the same grid produces a 60mm column beside 100mm of nothing. */
  [data-legal-doc] .lg\:grid,
  [data-legal-doc] [data-clause] {
    display: block;
  }

  [data-legal-doc] h1 {
    font-size: 22pt;
    line-height: 1.1;
    margin-bottom: 4mm;
    /* The display face is set inline on the element, so this is one of the two
       places the cascade cannot reach without help. */
    font-stretch: normal !important;
  }

  [data-legal-doc] h1,
  [data-legal-doc] h2,
  [data-legal-doc] h3,
  [data-legal-doc] th,
  [data-legal-doc] strong,
  [data-legal-doc] mark {
    color: #000;
  }

  [data-legal-doc] h2 {
    font-size: 11.5pt;
    margin-top: 6mm;
    /* A clause heading orphaned at the foot of a page is the classic printed
       contract defect. */
    break-after: avoid;
    page-break-after: avoid;
  }

  [data-legal-doc] p,
  [data-legal-doc] [data-sub],
  [data-legal-doc] li,
  [data-legal-doc] td,
  [data-legal-doc] a {
    color: #111;
    font-size: 9.5pt;
    line-height: 1.45;
  }

  /* Small caps for the machine-readable furniture: version, date, clause
     numbers. Retaining the monospace face at 11px would print grey and thin. */
  [data-legal-doc] .tech {
    color: #444;
    font-size: 8pt;
  }

  /* The plain-language column becomes an indented note under its clause. Kept
     visually distinct, because a reader who cannot tell the summary from the
     clause has been handed a document with two operative texts in it. */
  [data-legal-doc] [data-plain] {
    border-left: 1.5pt solid #999;
    margin: 2.5mm 0 0 6mm;
    padding-left: 3mm;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  [data-legal-doc] [data-plain] p {
    color: #444;
    font-size: 8.5pt;
    font-style: italic;
  }

  [data-legal-doc] [data-plain] .tech {
    font-style: normal;
  }

  [data-legal-doc] table {
    width: 100%;
    min-width: 0;
    break-inside: auto;
  }

  [data-legal-doc] tr {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  [data-legal-doc] th,
  [data-legal-doc] td {
    border-bottom: 0.5pt solid #ccc;
    padding: 1.5mm 4mm 1.5mm 0;
  }

  /* A URL is the only form in which a link survives printing. Restricted to
     absolute ones: expanding every in-page clause anchor would put a hash after
     half the sentences in the contents. */
  [data-legal-doc] a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 8pt;
    color: #555;
    word-break: break-all;
  }

  /* Backgrounds and borders drawn for a dark interface. The panel fills print
     as grey boxes and the dividers as black bars. */
  [data-legal-doc] [class*='bg-ink'],
  [data-legal-doc] [class*='bg-flag'],
  [data-legal-doc] [class*='bg-beam'] {
    background: transparent !important;
  }

  [data-legal-doc] [class*='border-ink'],
  [data-legal-doc] [class*='border-flag'] {
    border-color: #bbb;
  }
}
/*
 * THE CALM SYSTEM — Direction B ("The Instrument"), ported.
 *
 * Source: `docs/superpowers/mockups/direction-b-instrument.html`.
 * Directive: `docs/superpowers/specs/2026-08-11-calm-system-rollout.md`.
 *
 * ---------------------------------------------------------------------------
 * THIS IS A PORT OF THAT FILE'S CSS, NOT AN INTERPRETATION OF ITS MOOD
 * ---------------------------------------------------------------------------
 *
 * Five previous attempts at rolling a mock across this frontend failed the same
 * way, and the owner named it exactly: they "kept just generally taking a vague
 * pattern from it and bandaiding it on top of the existing frontend", losing
 * "the pure beauty and actual UX that comes from the mocks."
 *
 * The cause was always the direction of travel — start at the existing
 * component, edit it toward the mock, stop when it feels close. So this file
 * travels the other way. Every declaration below is LIFTED from B: the same
 * values, the same line heights, the same shadows, the same spacing beats. Where
 * a number here differs from the mock, that is a defect in this file.
 *
 * Two mechanical changes were required and they are the only two:
 *
 *   1. CLASS NAMES are prefixed `c-`. `.ico` and `.sheet` already exist in
 *      `mock.css` and would collide; prefixing all of them rather than the two
 *      keeps one rule instead of an exception list.
 *   2. CUSTOM PROPERTIES are prefixed `--c-`. B names its tokens `--paper`,
 *      `--flag`, `--beam` — the same names `mock.css` defines with DIFFERENT
 *      dark-mode values. A `.calm` subtree inside `.mockroot` would have
 *      silently redefined them for every inherited rule underneath.
 *
 * Neither changes an appearance. Nothing else was adapted, rounded or improved.
 *
 * ---------------------------------------------------------------------------
 * ADDITIVE AND NON-BREAKING, BY CONSTRUCTION
 * ---------------------------------------------------------------------------
 *
 * Every selector here is either `.calm`-scoped or `c-`-prefixed, so no existing
 * element can match one. Existing surfaces render exactly as they did until a
 * later wave opts them in deliberately. `mock.css` sits in `@layer components`
 * and this file is unlayered — unlayered styles beat layered ones whatever the
 * specificity, so an opted-in subtree gets these rules without a !important or
 * a specificity war.
 */

/* ==========================================================================
   1. THE TOKENS — B's `:root` block, values verbatim
   ========================================================================== */

.calm {
  /* ---- paper: the maker surface ---------------------------------------- */
  --c-paper: #FBF8F2;
  --c-ink: #211D15;
  --c-ink-2: #6B6455;
  --c-hairline: rgba(33, 29, 21, .14);
  /*
   * NOT THE MOCK'S VALUE, AND IT MUST NOT BE "RESTORED" TO IT.
   *
   * Every mock in `docs/superpowers/mockups/` draws this grey as #9A927F, which
   * measures 2.92:1 on #FBF8F2 paper — it fails AA at body size AND fails the
   * 3.0 floor for large text, so there is no size at which it is legal. This is
   * the one place the "lift the mock verbatim" method does not apply, and the
   * Rules and Carousel conversions arrived at it independently.
   *
   * It carries the provenance line, the rack's count, the figure labels and
   * every placeholder on the converted surfaces — all at 9–10.5px, which is the
   * size where a failing ratio stops being a technicality.
   *
   * Darkened along its OWN hue rather than swapped for a cool grey, so the
   * paper stays warm: #767061 is 4.65:1 on the paper and 4.85:1 on the #FFFDF9
   * card. The standing note names #5F5A6E as "grey on paper that works" — it
   * does (6.24:1) and it is cool, which would lay a cold line under a warm
   * surface. This is that rule honoured in the paper's own temperature.
   *
   * Computed, not judged: an earlier pass on this codebase tried to fix a
   * failing grey by LIGHTENING it and made it worse.
   */
  --c-meta: #767061;

  /* ---- frame: the governance instrument --------------------------------
     Softened 2026-08-11 on the owner's note: the near-black (#17151C) read as
     stark against the paper. The frame is graphite — still clearly the
     instrument, no longer a hard edge. */
  --c-frame: #2B2833;
  --c-frame-2: #37333F;
  --c-frame-line: #443F4E;
  --c-readout: #BEB8CA;
  /*
   * NOT THE MOCKS' VALUE, AND IT MUST NOT BE "RESTORED" TO IT.
   *
   * The third grey of the same kind as `--c-meta` above and the `.c-menu` aside
   * below, found when the shell put it on every screen in the product rather
   * than on two studio plates. Every mock draws this as #847D93, which measures
   * 3.67:1 on `--c-frame` and 3.12:1 on `--c-frame-2` — short of AA at the two
   * sizes it is actually used at: the status bar's aux facts (9.5px) and the
   * brand switcher's account name (12.5px). Neither is large text at any
   * reading of the rule.
   *
   * Lightened along its OWN hue rather than swapped for a cool grey, and
   * LIGHTENED IS THE RIGHT DIRECTION HERE — this is light ink on a dark ground,
   * the opposite case from `--c-meta`, where an earlier pass lightened dark ink
   * on light paper and made it worse. #9F9AAB is 5.28:1 on the frame and
   * 4.50:1 on `--c-frame-2`, which is the hover ground the switcher and the
   * lens both land on. Computed, not judged.
   *
   * It reaches both studios' plates too, which is deliberate: one token, one
   * instrument, and the change is legibility in every place it lands.
   */
  --c-readout-dim: #9F9AAB;
  --c-readout-hi: #F4F2F8;

  /* ---- the signature and the affirmation -------------------------------
     THE ONLY COLOURS WITH MEANING. The pink squiggle stops a release at full
     tone and needs a person at soft tone; the beam is affirmation and focus.
     Everything else on a calm surface is ink, paper and graphite.

     There is no orange token and there must never be one — standing owner
     rule. Orange/terracotta reads as AI-default, and a decorative hue sitting
     beside these four would drain the meaning out of all of them. */
  --c-flag: #D6006E;
  --c-flag-soft: #E489B6;
  --c-beam: #0B756F;
  --c-beam-frame: #22E0D5;

  /* ---- the frame's voice entering the margin ---------------------------- */
  --c-note-bg: #F4F2F6;
  --c-note-line: #DAD6E2;

  /* ---- the three faces --------------------------------------------------
     Chrome is sans, content is serif, and mono is IDENTIFIERS — a revision, a
     fingerprint, an id, code. "Governance is mono" was the rule here until
     2026-09-16, and what it produced was every governed line on every screen
     set in a geometric mono: the look the owner threw out. Governance is now
     carried by restraint and hierarchy, not by a typeface. See §2. */
  --c-sans: 'Switzer', 'Avenir Next', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --c-serif: 'Charter', 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
  --c-mono: 'SF Mono', ui-monospace, 'Menlo', 'Cascadia Mono', monospace;

  /* ======================================================================
     2. THE TYPE SCALE — three roles, and a step only exists if B uses it
     ======================================================================

     | Role       | Face  | Used for                                        |
     |------------|-------|-------------------------------------------------|
     | Chrome     | sans  | navigation, labels, controls, page furniture    |
     | Content    | serif | the customer's own words, where they are subject|
     | Identifier | mono  | revisions, fingerprints, ids, code              |

     THE THIRD ROW SAID "Governance | mono | readouts, counts, rule identities,
     record lines" UNTIL 2026-09-16, and the paragraph under it argued that mono
     was an accent which would lose its meaning if it ever reached ordinary UI
     text. The argument was right and the row had already lost it: 255 mono
     declarations across six stylesheets, setting every date, count, column
     header and status word in the product. A signal on everything is not a
     signal, and what it actually signalled to the owner was a machine writing
     its own interface.

     So mono now means one thing: the exact characters matter and somebody may
     have to compare them. `rev 4` and `b222fe34` keep it. `Changed 14 Sep` and
     `3 rules` do not. Governance is carried by restraint and hierarchy, which
     is what the rest of this file is for.

     These are B's own sizes, enumerated from its stylesheet rather than fitted
     to a ratio — a modular scale would have been an invention, and every value
     that is not B's is a value that drifts. */

  /* Governance (mono). Four steps, and only ever these four. */
  --c-gov-xs: 8.5px;      /* provenance lines, menu group labels */
  --c-gov-sm: 9.5px;      /* the aux readout, mono asides in menus */
  --c-gov-md: 10.5px;     /* the plate: uppercase, .13em */
  --c-gov-lg: 12px;       /* the status sentence — sentence case, it speaks English */
  --c-gov-track: .13em;   /* the plate's and provenance's letter-spacing */
  --c-gov-track-wide: .16em;

  /* Chrome (sans). */
  --c-ui-xs: 11px;        /* tooltips */
  --c-ui-sm: 12px;        /* note actions, dense secondary controls */
  --c-ui-md: 13px;        /* menu items */
  --c-ui: 13.5px;         /* THE DEFAULT control and label size */
  --c-ui-lg: 14.5px;      /* console input, body prose in chrome */
  --c-ui-title: 23px;     /* a screen's own title */
  --c-ui-display: 28px;   /* the sheet's heading */

  /* Content (serif). */
  --c-doc-sm: 13px;       /* a quoted rule, in the margin */
  --c-doc-quiet: 15px;    /* the quiet note — disclosures, hashtags */
  --c-doc: 19px;          /* the customer's words */
  --c-doc-hook: 22px;     /* the first line, which on social is the whole game */

  --c-lh-doc: 32px;       /* THE MEASURE. Everything in §3 is a multiple. */
  --c-lh-doc-quiet: 26px;
  --c-lh-doc-hook: 34px;

  /* ======================================================================
     3. THE SPACING RHYTHM — derived from the measure, not chosen
     ======================================================================

     The owner's complaint, verbatim: the platform "needs to breathe", "bands
     stack against each other; blocks of copy sit tight to their controls; the
     eye never gets a rest between sections."

     B answers it with one number. `.pline { margin: 0 0 48px }`, commented in
     the mock as "1.5lh beat between blocks" — 1.5 × the 32px content line
     height. Every other gap in the mock falls on the same grid:

         .sheet h2  margin-bottom  40px  = 1.25lh
         .pline     margin-bottom  48px  = 1.5lh   <- the block beat
         .sheet     padding-top    60px  ~ 1.875lh
         .sheet     padding-bottom 90px  ~ 2.8lh

     So the rhythm is not a set of round numbers somebody liked. It is the
     line height, counted. That is why it breathes: the eye is resting for a
     whole line and a half between blocks, where today's bands rest for 14px.

     The sub-beat steps below the line are B's own control paddings — the
     inside of a menu item, the gap in a plate — and they are deliberately NOT
     on the lh grid, because furniture is measured against the hand, not the
     page. */

  --c-beat: var(--c-lh-doc);              /* 32px — one line of content */
  --c-beat-half: 16px;                    /* 0.5lh */
  --c-beat-3q: 24px;                      /* 0.75lh */
  --c-beat-125: 40px;                     /* 1.25lh — a heading to its body */
  --c-beat-15: 48px;                      /* 1.5lh  — BLOCK TO BLOCK */
  --c-beat-open: 60px;                    /* the top of a sheet */
  --c-beat-close: 90px;                   /* the bottom of a sheet */

  /* Furniture, inside the hand's reach. B's own control metrics. */
  --c-gap-tight: 4px;                     /* icons in a capsule */
  --c-gap-xs: 6px;
  --c-gap-sm: 8px;
  --c-gap: 10px;
  --c-gap-md: 14px;                       /* plate right-hand cluster */
  --c-gap-lg: 18px;                       /* plate, crumb to controls */
  --c-gap-xl: 20px;                       /* status bar */

  --c-pad-plate: 0 14px 0 18px;
  --c-pad-status: 10px 18px;
  --c-pad-menu-item: 7px 9px;
  --c-pad-note: 13px 15px 12px;

  --c-h-plate: 46px;
  --c-h-status: 44px;
  --c-h-control: 30px;                    /* an icon button, a lens segment */
  --c-measure: 620px;                     /* the sheet, and the console under it */

  /* ======================================================================
     4. ELEVATION — B's four shadows, verbatim
     ======================================================================
     Two-stop every time: a 1–3px contact shadow that seats the edge, and a
     wide soft one that lifts it. The ink is rgba(23,21,28) throughout — the
     shadow stayed near-black when the frame softened to graphite, because a
     shadow is ink on paper, not a tint of the thing casting it. */

  --c-e-note: 0 1px 2px rgba(23, 21, 28, .05), 0 10px 30px rgba(23, 21, 28, .09);
  --c-e-capsule: 0 2px 5px rgba(23, 21, 28, .07), 0 10px 34px rgba(23, 21, 28, .12);
  --c-e-menu: 0 3px 8px rgba(23, 21, 28, .08), 0 14px 40px rgba(23, 21, 28, .18);
  --c-e-instrument: 0 2px 4px rgba(23, 21, 28, .08), 0 22px 70px rgba(23, 21, 28, .22);
  /* The selection capsule is graphite on paper and needs a darker seat. */
  --c-e-seltool: 0 3px 8px rgba(23, 21, 28, .2), 0 12px 34px rgba(23, 21, 28, .3);

  /* ---- radii: B's, enumerated ------------------------------------------ */
  --c-r-xs: 4px;
  --c-r-sm: 6px;
  --c-r: 9px;
  --c-r-md: 10px;
  --c-r-lg: 14px;
  --c-r-pill: 999px;

  /* ---- icons: ONE stroke weight, ONE size set -------------------------- */
  --c-ico: 15px;
  --c-ico-sm: 13px;
  --c-ico-lg: 18px;
  --c-ico-stroke: 1.5;

  /* ======================================================================
     4b. THE PLATFORM SCALE — the tokens `platform-rules.html` adds
     ======================================================================

     Direction B at platform scale, from the four `platform-*.html` mocks whose
     `:root` block is byte-identical across all four. Everything B already
     names is above and is NOT restated: `--paper`, `--p-ink`, `--p-ink-2`,
     `--p-hairline`, `--p-meta`, the frame six, the four meaning colours, the
     three faces and `--lift-3` (which is `--c-e-seltool`, to the byte) all
     match what §1 already carries.

     These six are the ones the platform pages add, and the one that differs:
     the platform mock's `--r-lg` is 12px where the studio mock's is 14px, so
     it is named for what it is rather than overwriting a value the studios
     are already drawn with. */
  --c-card: #FFFDF9;              /* platform --card: a raised sheet on paper */
  --c-flag-wash: #FBEEF4;         /* platform --flag-wash */
  --c-gap-row: 12px;              /* platform --gap-row */
  --c-gap-block: 22px;            /* platform --gap-block */
  --c-gap-section: 56px;          /* platform --gap-section: sections breathe */
  --c-r-card: 12px;               /* platform --r-lg */
  --c-lift-1: 0 1px 2px rgba(23, 21, 28, .05);   /* platform --lift-1 */
}

/*
 * DARK.
 *
 * B has no dark mode — it commits to one look, and inventing a second palette
 * for it is exactly the "vague pattern" failure this file exists to avoid. But
 * the app has a dark theme, and a light-only island inside it is a visible
 * defect at night.
 *
 * So nothing here is invented either. The frame tokens do not move: graphite
 * IS the dark material and it reads correctly on a dark ground. The paper
 * tokens invert to `mock.css`'s own committed dark surface values, and the
 * meaning colours take `mock.css`'s own dark `--flag` and `--beam`. Two
 * committed sources, no third opinion.
 */
@media (prefers-color-scheme: dark) {
  .calm:not([data-theme='light'] .calm) {
    --c-paper: #16151C;
    --c-ink: #F0EEF4;
    --c-ink-2: #BDB8C8;
    --c-hairline: rgba(240, 238, 244, .14);
    --c-meta: #8D8799;
    --c-flag: #FF2E8E;
    --c-flag-soft: #FF5AA5;
    --c-beam: #22E0D5;
    --c-note-bg: #1B1A22;
    --c-note-line: #2A2833;
    --c-card: #1B1A22;
    --c-flag-wash: rgba(255, 46, 142, .12);
  }
}

[data-theme='dark'] .calm {
  --c-paper: #16151C;
  --c-ink: #F0EEF4;
  --c-ink-2: #BDB8C8;
  --c-hairline: rgba(240, 238, 244, .14);
  --c-meta: #8D8799;
  --c-flag: #FF2E8E;
  --c-flag-soft: #FF5AA5;
  --c-beam: #22E0D5;
  --c-note-bg: #1B1A22;
  --c-note-line: #2A2833;
  --c-card: #1B1A22;
  --c-flag-wash: rgba(255, 46, 142, .12);
}

/* ==========================================================================
   5. THE INSTRUMENT — B's frame, verbatim
   ==========================================================================
   A warm paper surface where the work lives, held inside a graphite frame
   where the governance voice speaks. Both tiers, one screen, no seam: this is
   how the two-tier design bar is resolved rather than contradicted.
   ========================================================================== */

.c-instrument {
  display: flex;
  flex-direction: column;
  border-radius: var(--c-r-lg);
  overflow: hidden;
  box-shadow: var(--c-e-instrument);
  position: relative;
}

/* ---- the top plate: title, the lens, one verb, one menu -----------------
   Six labelled buttons die here. That header row is the emblem of "too many
   voices at once" and the plate is what replaces it.

   THE PLATE IS NOT A READOUT. It carries a brand's name, a document's name
   and the controls beside them, and it carried all of it in 10.5px uppercase
   mono at .13em. None of those is an identifier — they are names — and the
   plate is on every converted screen, so it set the register for the whole
   product. Sans at `--c-ui-sm`, sentence case. What still says "the record is
   speaking" is the graphite ground; that was always the part doing the work.
   The `--c-gov-*` tokens are untouched and are still what an identifier
   takes. */
.c-plate {
  background: var(--c-frame);
  color: var(--c-readout);
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--c-gap-lg);
  padding: var(--c-pad-plate);
  min-height: var(--c-h-plate);
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  position: relative;
  z-index: 30;
}

.c-plate .c-crumb {
  display: flex;
  align-items: center;
  gap: var(--c-gap);
  white-space: nowrap;
  overflow: hidden;
  transition: opacity .16s ease-out;
}

.c-plate .c-crumb > span:first-of-type {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* The beam square. The one affirmation mark on the plate. */
.c-plate .c-crumb i {
  width: 7px;
  height: 7px;
  background: var(--c-beam-frame);
  border-radius: 2px;
  flex: none;
}

.c-plate .c-crumb b {
  color: var(--c-readout-hi);
  font-weight: 600;
}

.c-plate .c-rhs {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--c-gap-md);
  white-space: nowrap;
  position: relative;
  transition: opacity .16s ease-out;
}

/* ---- the bottom plate: the readout -------------------------------------
   The co-reader's mouth: ONE grammatical sentence. It was mono "because the
   instrument is speaking", and sentence case "because it speaks English" —
   the second half of that argument finished the first. A sentence is a
   sentence whoever says it. Sans, at the same 12px the governance step used,
   so nothing moves but the face. */
.c-status {
  background: var(--c-frame);
  color: var(--c-readout);
  flex: none;
  min-height: var(--c-h-status);
  display: flex;
  align-items: center;
  gap: var(--c-gap-xl);
  padding: var(--c-pad-status);
  font-family: var(--c-sans);
  font-size: var(--c-gov-lg);
  position: relative;
  z-index: 12;
}

.c-status .c-sentence {
  display: flex;
  align-items: center;
  gap: 9px;
  letter-spacing: .01em;
  color: #C9C4D4;
  transition: opacity .16s ease-out;
}

.c-status .c-sentence i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--c-beam-frame);
  display: block;
  flex: none;
  opacity: 0;
  transition: opacity .24s ease-out;
}

.c-status .c-sentence.reading i {
  opacity: 1;
  animation: c-breathe 1.2s ease-in-out infinite;
}

@keyframes c-breathe {
  0%, 100% { opacity: 1 }
  50% { opacity: .25 }
}

/* Nothing stops a release. The one place the beam speaks on the status bar. */
.c-status .c-sentence.clear { color: var(--c-beam-frame) }

/* The facts riding at the end of the sentence — "14 rules in force", "68
   words". Counts, so they take the plate's sans with it, and the caps and
   the .11em that made small mono legible go with the mono. Up to
   `--c-ui-xs`: 9.5px was tuned for a monospace and is a squint in a sans. */
.c-status .c-aux {
  margin-left: auto;
  font-size: var(--c-ui-xs);
  color: var(--c-readout-dim);
  white-space: nowrap;
  transition: opacity .16s ease-out;
}

/* ---- the paper between them -------------------------------------------- */
.c-paper {
  flex: 1;
  overflow-y: auto;
  background: var(--c-paper);
  color: var(--c-ink);
  position: relative;
}

/*
 * The sheet: the measure, and the rhythm that breathes.
 *
 * 60px of air before the first word and 90px after the last. This is the
 * single most direct answer to "nothing breathes" — a band today opens 14px
 * from whatever is above it.
 */
.c-sheet {
  max-width: var(--c-measure);
  margin: 0 auto;
  padding: var(--c-beat-open) 0 var(--c-beat-close);
  position: relative;
}

.c-sheet h2 {
  font-size: var(--c-ui-display);
  font-weight: 600;
  letter-spacing: -.005em;
  line-height: 1.25;
  margin: 0 0 var(--c-beat-125);
}

/* THE BLOCK BEAT. 1.5 line heights between blocks, and nothing less. */
.c-block { position: relative; margin: 0 0 var(--c-beat-15) }
.c-block:last-child { margin-bottom: 0 }

.c-block p {
  margin: 0;
  font-family: var(--c-serif);
  font-size: var(--c-doc);
  line-height: var(--c-lh-doc);
  color: var(--c-ink);
}

.c-block.hook p {
  font-size: var(--c-doc-hook);
  line-height: var(--c-lh-doc-hook);
  font-weight: 500;
  letter-spacing: -.012em;
}

.c-block.quiet p {
  font-size: var(--c-doc-quiet);
  line-height: var(--c-lh-doc-quiet);
  color: var(--c-ink-2);
}

/* ==========================================================================
   6. ICONS — one stroke weight, one size set, and a tooltip is not optional
   ========================================================================== */

/*
 * B's `.ico`, verbatim: 15px, stroke 1.5, round caps and joins.
 *
 * `mock.css` says 16px and stroke 1.6 and is not wrong so much as a different
 * hand — the drift the directive names as complaint 3, "stroke weights and
 * sizes drift". One weight, one set, from here on.
 */
.c-ico {
  width: var(--c-ico);
  height: var(--c-ico);
  stroke: currentColor;
  fill: none;
  stroke-width: var(--c-ico-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
  display: block;
}

.c-ico.sm { width: var(--c-ico-sm); height: var(--c-ico-sm) }
.c-ico.lg { width: var(--c-ico-lg); height: var(--c-ico-lg) }

/*
 * TOOLTIPS: every icon explains itself on rollover.
 *
 * The rule is "a tooltip is REQUIRED on every icon-only control". CSS cannot
 * require anything, so the requirement is enforced in TypeScript — see
 * `iconButton.tsx`, whose `tip` prop has no default and no optional marker,
 * and which writes the same words into `aria-label` so the tooltip is not the
 * only copy of them. This rule is what those words look like.
 *
 * On `:focus-visible` as well as `:hover`, because a keyboard reaches these.
 */
[data-tip] { position: relative }

[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-frame);
  color: #E7E4EE;
  font-family: var(--c-sans);
  font-size: var(--c-ui-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.3;
  padding: 5px 9px;
  border-radius: var(--c-r-sm);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease-out .3s;
  z-index: 40;
}

[data-tip]:hover::after,
[data-tip]:focus-visible::after { opacity: 1 }

[data-tip].tip-below::after { bottom: auto; top: calc(100% + 9px) }
[data-tip].tip-left::after { left: auto; right: 0; transform: none }
[data-tip].tip-right::after { left: 0; right: auto; transform: none }

/* An icon-only control on the frame. */
.c-iconbtn {
  background: none;
  border: 0;
  color: var(--c-readout);
  cursor: pointer;
  width: var(--c-h-control);
  height: var(--c-h-control);
  display: grid;
  place-items: center;
  border-radius: var(--c-r-sm);
  padding: 0;
}

.c-iconbtn:hover { background: var(--c-frame-2); color: var(--c-readout-hi) }
.c-iconbtn[disabled] { opacity: 1; color: var(--c-readout); cursor: default }
.c-iconbtn[disabled]:hover { background: none; color: var(--c-readout) }

/* The same control on paper rather than on the frame. */
.c-iconbtn.on-paper { color: var(--c-ink-2) }
.c-iconbtn.on-paper:hover { background: rgba(33, 29, 21, .06); color: var(--c-ink) }

/* A segmented group of icon controls — B's lens. */
.c-lens {
  display: flex;
  border: 1px solid var(--c-frame-line);
  border-radius: var(--c-r-sm);
  overflow: hidden;
}

.c-lens button {
  background: none;
  border: 0;
  color: var(--c-readout-dim);
  cursor: pointer;
  width: var(--c-h-control);
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
}

.c-lens button.on { background: var(--c-frame-2); color: var(--c-beam-frame) }
.c-lens button:hover:not(.on) { color: var(--c-readout-hi) }

/* ==========================================================================
   7. MENUS — secondary commands live one level down, never on the surface
   ========================================================================== */

.c-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: #FFFDF9;
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-md);
  padding: var(--c-gap-xs);
  min-width: 220px;
  box-shadow: var(--c-e-menu);
  z-index: 35;
}

.c-menu[hidden] { display: none }

.c-menu button {
  display: flex;
  align-items: center;
  gap: var(--c-gap);
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  font-family: var(--c-sans);
  font-size: var(--c-ui-md);
  color: #211D28;
  padding: var(--c-pad-menu-item);
  border-radius: var(--c-r-sm);
  cursor: pointer;
  letter-spacing: 0;
  text-transform: none;
}

.c-menu button:hover:not([disabled]) { background: #F1EEE6 }
.c-menu button[disabled] { opacity: .4; cursor: default }

/* The fact riding alongside a menu row's label. What it actually carries is a
   seat's role — "account", "limited", "owner" — and sometimes a count. Role
   words are English and counts are not identities, so this is sans now; it is
   held apart from the label by position, colour and size, which is enough. */
.c-menu .c-aside {
  margin-left: auto;
  /* A seat's role is three words at most and must not be the thing that gives
     way: without this a double-barrelled name shrank "limited" to "limitec"
     against the menu's edge. Seen in Chrome on the fixture account. */
  flex: none;
  white-space: nowrap;
  font-family: var(--c-sans);
  font-size: var(--c-ui-xs);
  /* The mocks draw this at #847E92, which is 3.84:1 on the #FFFDF9 card and
     fails AA. Same hue, darkened to 5.03:1. See `--c-meta` above: the mocks
     are the source for structure, not for contrast. */
  color: #716B7F;
}

/* A menu's group label — "This text", "This frame", "Set aside because". It
   names the rows under it. A label is not a readout, which is the sentence
   §2 has always ended on; it is the face that has changed, not the rule. */
.c-menu .c-glab {
  font-family: var(--c-sans);
  font-size: var(--c-ui-xs);
  font-weight: 600;
  /* #847E92 in the mocks: 3.84:1 on the card, fails AA. Same hue at 5.03:1. */
  color: #716B7F;
  padding: 6px 9px 3px;
}

.c-menu hr { border: 0; border-top: 1px solid #ECE9E0; margin: 5px 4px }

/*
 * THE SAME CARD, OPENED AT THE CURSOR — see `contextMenu.tsx`.
 *
 * `2026-08-12-right-click.md` says two things about the chassis and they pull
 * against each other: *"Reuse the menu that already exists — the `···` popover
 * … Do not draw a second menu"*, and *"Graphite, the same 29px row metrics as
 * `.c-seltool`."* Reuse won, because it is the law the document states twice
 * and in bold, and because a graphite card WOULD be the second menu: the
 * Bench's `···` (`bench.css`) and this one are already the same paper card
 * measured twice, and a third material over a graphite bench and a cream paper
 * is a new object on both surfaces rather than a shared one.
 *
 * What is taken from `.c-seltool` is the metric the document actually names —
 * the 29px row — so the two contextual objects agree on rhythm. Position is
 * set inline, from the pointer; only the offsets that would fight it are
 * neutralised here.
 */
.c-menu-at-cursor {
  /* Above the capsule (40) and the Bench's own plate menu (55). */
  z-index: 60;
  max-height: min(72vh, 560px);
  overflow: auto;
}

.c-menu-at-cursor button { min-height: 29px }

/*
 * A refused item is dimmed but still reachable — see the note in
 * `contextMenu.tsx`. `[disabled]` would have taken it out of the arrow walk,
 * and the one item worth reaching is the one that explains itself.
 */
.c-menu-at-cursor button[aria-disabled='true'] { opacity: .4; cursor: default }
.c-menu-at-cursor button[aria-disabled='true']:hover { background: none }

/* ==========================================================================
   8. SELECTION IS THE PRIMARY VERB — B's `.seltool`
   ==========================================================================
   "Acting on a thing starts by selecting it." In the mock this capsule hangs
   over a text selection and hands you the verbs for it. On a list it hangs
   over a row selection and does the same job — icons only, every one of them
   explaining itself on rollover.

   Kept as a floating graphite capsule rather than becoming a band across the
   table, because the calm state of a list is a list: a permanent toolbar over
   it is furniture for an act most visits never perform.
   ========================================================================== */

.c-seltool {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--c-frame);
  border-radius: var(--c-r);
  padding: var(--c-gap-tight);
  box-shadow: var(--c-e-seltool);
  z-index: 20;
}

.c-seltool > button {
  background: none;
  border: 0;
  color: #C9C4D4;
  cursor: pointer;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--c-r-sm);
  padding: 0;
  /* B's own `.seltool > button`, restored. Bold and italic are drawn as
     LETTERFORMS rather than as icons — `<b>B</b>`, `<i>I</i>` — so the capsule
     needs a type face and a size for them, and dropping these left the two
     glyphs falling back to the page's sans at whatever size it inherited.
     Copy Studio kept the mock's values in its own duplicate of this chassis;
     they belong here, where the one chassis is defined. */
  font-family: var(--c-serif, 'Charter', 'Iowan Old Style', Georgia, serif);
  font-size: 14px;
}

.c-seltool > button:hover:not([disabled]) { background: var(--c-frame-2); color: #fff }
.c-seltool > button[disabled] { opacity: .4; cursor: default }

.c-seltool .c-sep { width: 1px; height: 16px; background: var(--c-frame-line); margin: 0 4px }

/* The count the capsule is acting on — "3 selected". A number and a state
   word, and neither is a thing anybody spells out. Sans, sentence case, with
   tabular figures so the capsule does not shift width as the count climbs. */
.c-seltool .c-count {
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  font-variant-numeric: tabular-nums;
  color: var(--c-readout-hi);
  padding: 0 var(--c-gap-sm) 0 var(--c-gap-xs);
  white-space: nowrap;
}

/*
 * Floating over the paper, centred, the way B hangs it over a selection.
 *
 * FIXED, NOT STICKY, AND THAT IS THE WHOLE POINT.
 *
 * This was `position: sticky; bottom: 14px`, which is correct only when the
 * capsule's own scroll container is the thing that scrolls. In the mock it is:
 * `.instrument` has `height: min(900px, 90vh)` and `.paper` is the flex child
 * that scrolls inside it. A list embedded in an ordinary page has no such
 * height, so `.c-paper` never scrolls, the PAGE does — and a sticky element
 * with no scrolling ancestor simply sits in normal flow.
 *
 * Found in a browser, not by a test: the capsule rendered at the very bottom
 * of the table's content, so selecting anything outside the last screenful of
 * rows gave no visible confirmation that a selection had happened at all. The
 * suite passed the whole time, because jsdom has no layout.
 *
 * Fixed to the viewport, so the verbs are in the same place whatever is
 * selected and wherever the reader has scrolled to.
 */
.c-seltool.floating {
  position: fixed;
  bottom: var(--c-beat-3q);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100vw - 2 * var(--c-gap-md));
  z-index: 40;
}

/* ==========================================================================
   8b. THE CONSOLE CAPSULE — B's `.capsule`, verbatim
   ==========================================================================
   In the mock this is the console: a pill on the fascia that writes and edits.
   On a list surface the same shape carries the filter — one field, an icon
   that names what it does, a mono key hint, and a send/act at the end. It is
   the mock's only text-input shape, so it is the one a filter uses.
   ========================================================================== */

.c-capsule {
  display: flex;
  align-items: center;
  gap: 11px;
  background: #FFFDF9;
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-pill);
  padding: 9px 9px 9px 17px;
  box-shadow: var(--c-e-capsule);
}

.c-capsule:focus-within { border-color: #B9B3C6 }
.c-capsule .c-nib { color: var(--c-beam) }

.c-capsule input {
  flex: 1;
  border: 0;
  background: none;
  outline: none;
  font-family: var(--c-sans);
  font-size: var(--c-ui-lg);
  color: var(--c-ink);
  min-width: 0;
}

.c-capsule input::placeholder { color: var(--c-meta) }

/* A mono hint riding in a sans control — a key name is a literal, so it is
   governance voice. */
.c-capsule .c-khint {
  font-family: var(--c-mono);
  font-size: 10px;
  color: var(--c-meta);
  flex: none;
}

/* A filter capsule sits on the plate rather than the paper, so it takes the
   frame's ground instead of the note's. */
.c-plate .c-capsule {
  background: var(--c-frame-2);
  border-color: var(--c-frame-line);
  box-shadow: none;
  padding: 5px 6px 5px 12px;
}

/* `letter-spacing: 0` and `text-transform: none` stood here to undo what the
   plate imposed on everything inside it. The plate imposes neither now. */
.c-plate .c-capsule input {
  font-size: var(--c-ui-sm);
  color: var(--c-readout-hi);
  font-family: var(--c-sans);
}

.c-plate .c-capsule input::placeholder { color: var(--c-readout-dim) }
.c-plate .c-capsule .c-nib { color: var(--c-readout-dim) }

/*
 * THE ONE VERB. B's `.signoff` — a bordered control that is dim until it is
 * earned, and takes the beam when it opens. The pattern generalises: a
 * primary act that is not currently available says so by being dim rather than
 * by disappearing, so nobody hunts for a control that was never there.
 *
 * It says "Sign off", not `SIGN OFF`. A verb is what will happen when you
 * press it — the most ordinary English on the screen — and setting it in the
 * identifier face made the one act on the plate read as a serial number.
 */
.c-verb {
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  font-weight: 600;
  background: none;
  border: 1px solid var(--c-frame-line);
  border-radius: var(--c-r-sm);
  color: var(--c-readout-hi);
  padding: 6px 13px;
  opacity: .32;
  cursor: default;
  transition: opacity .24s ease-out, border-color .24s ease-out, color .24s ease-out;
}

.c-verb.earned {
  opacity: 1;
  border-color: var(--c-beam-frame);
  color: var(--c-beam-frame);
  cursor: pointer;
}

/* A fact that fades in on the plate — B's `.varchip`. It names the surfaces
   one post is read on, so it is names, and it takes the plate's sans with the
   plate; 9px and .1em were the settings a small mono needed.
   Named `.c-varchip` rather than `.c-chip`, which is what B calls it and which
   frees `.c-chip` for the platform mocks' filter/toggle chip in §12. Two
   unrelated objects were sharing one class name and nothing rendered either. */
.c-varchip {
  margin-left: 4px;
  padding: 3px 8px;
  border: 1px solid var(--c-frame-line);
  border-radius: 5px;
  color: var(--c-beam-frame);
  font-size: var(--c-ui-xs);
  flex: none;
}

/* ==========================================================================
   9. CHROME RECEDES ON WORK AND RETURNS ON ATTENTION
   ==========================================================================
   B dims the frame on the first keystroke and brings it back on Escape or on
   pointer. The directive generalises it: "not every surface has a writing
   state, but every surface has a primary act, and the furniture around that
   act should be quieter than the act."

   So it is a class rather than a state. Put `c-recede` on a surface that has a
   primary act; mark the furniture `c-chrome`. The furniture goes soft and
   comes back on hover, on focus-within, and whenever the surface is marked
   `attention`. Never to zero — B's comment is "softly visible, never gone",
   and furniture that disappears is furniture nobody can find again.
   ========================================================================== */

.c-recede .c-chrome {
  opacity: .42;
  transition: opacity .16s ease-out;
}

.c-recede .c-chrome:hover,
.c-recede .c-chrome:focus-within,
.c-recede:hover .c-chrome,
.c-recede.attention .c-chrome { opacity: 1 }

/* The frame's two plates recede further than paper furniture does — they are
   the loudest thing on the screen when they are not needed. B's own values. */
.c-recede .c-plate .c-crumb { opacity: .34 }
.c-recede .c-plate .c-rhs { opacity: .22 }
.c-recede .c-status .c-aux { opacity: .3 }
.c-recede .c-status .c-sentence { opacity: .62 }

.c-recede:hover .c-plate .c-crumb,
.c-recede:hover .c-plate .c-rhs,
.c-recede:hover .c-status .c-aux,
.c-recede:hover .c-status .c-sentence,
.c-recede.attention .c-plate .c-crumb,
.c-recede.attention .c-plate .c-rhs,
.c-recede.attention .c-status .c-aux,
.c-recede.attention .c-status .c-sentence { opacity: 1 }

/* Work's searchable inventory is navigation. Its crumb and search placeholder
   use AA-safe frame tokens, so dimming their parent would turn them translucent. */
.c-recede.contrast-safe .c-plate .c-crumb,
.c-recede.contrast-safe .c-plate .c-rhs { opacity: 1 }

/* ==========================================================================
   9b. THE LIST — the one region B does not contain
   ==========================================================================

   STATED PLAINLY, BECAUSE IT IS THE ONE PLACE THIS FILE IS NOT A COPY.

   `direction-b-instrument.html` is a document editor. It has a paper sheet,
   margin marks, a console and two plates. It has no table: no rows, no
   columns, no headers, no checkboxes. So the chrome around a list is lifted
   verbatim above — the instrument, both plates, the selection capsule, the
   menu, the tooltips — and the row interior is the only thing designed.

   It is designed FROM the mock's measures rather than from the table that
   exists today, which was never consulted for how it should look:

     - A row's vertical rhythm is the block beat, halved. B rests 48px between
       blocks of prose; a row is a line, not a block, so it rests at
       `--c-beat-half` (16px) of padding. That is still four times the 4px a
       row breathes today, and it is the same grid.
     - A row's ground is `--c-paper`. There is no zebra striping and no washed
       row: B's only row-level colour is the squiggle, and a tinted row would
       be the `--flag-wash` this system deleted.
     - Rows are separated by `--c-hairline`, which is B's only divider.
     - THE TYPE ROLES DECIDE THE COLUMNS. A piece's title is the customer's own
       words, so it is serif at `--c-doc-quiet`. Column headers, campaign and
       channel are furniture, so they are sans at `--c-ui-sm`. Counts, sizes
       and dates are the record talking, so they are mono. This is the rule
       doing real work rather than being restated.
   ========================================================================== */

.c-list { width: 100%; border-collapse: collapse; margin: 0 }

/* Headers are FURNITURE. Sans, sentence case, quiet — not the uppercase mono
   the product uses today, which spends the governance voice on a label. */
.c-list thead th {
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-ink-2);
  text-align: left;
  padding: var(--c-gap-sm) var(--c-gap-md);
  border-bottom: 1px solid var(--c-hairline);
  white-space: nowrap;
  background: var(--c-paper);
  position: sticky;
  top: 0;
  z-index: 2;
}

.c-list tbody td {
  padding: var(--c-beat-half) var(--c-gap-md);
  border-bottom: 1px solid var(--c-hairline);
  vertical-align: middle;
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  color: var(--c-ink-2);
}

.c-list tbody tr:last-child td { border-bottom: 0 }
.c-list tbody tr:hover { background: rgba(33, 29, 21, .028) }

/* The row the keyboard is on. The beam, because focus is what the beam means. */
.c-list tbody tr:focus-visible {
  outline: 2px solid var(--c-beam);
  outline-offset: -2px;
}

.c-list tbody tr.picked { background: rgba(11, 117, 111, .07) }

/* THE CUSTOMER'S WORDS. Serif, because the title is theirs and not ours. */
.c-list .c-name {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--c-ink);
  font-family: var(--c-serif);
  font-size: var(--c-doc-quiet);
  line-height: var(--c-lh-doc-quiet);
}

.c-list .c-name:hover span { text-decoration: underline }
.c-list .c-name span { overflow: hidden; text-overflow: ellipsis; max-width: 34ch }

/* A fact in a cell — a count, a size, a date. Tabular figures rather than a
   second typeface; see `.c-gov` in §11. */
.c-list .c-gov { font-size: var(--c-gov-lg); color: var(--c-meta) }

/* A state word. Sans, sentence case, and its meaning is carried by the mark
   beside it rather than by a filled chip. */
.c-list .c-state { display: inline-flex; align-items: center; gap: var(--c-gap-xs) }

/* THE FINDINGS MARKER. B's margin mark: a short rule, not a badge. Full tone
   stops a release; soft tone needs a person. */
.c-list .c-state i {
  width: 14px;
  height: 0;
  border-top: 2px solid transparent;
  display: block;
  flex: none;
}

.c-list .c-state.stop i { border-top-color: var(--c-flag) }
.c-list .c-state.hold i { border-top-color: var(--c-flag-soft) }
.c-list .c-state.clear i { border-top-color: var(--c-beam) }
.c-list .c-state.stop { color: var(--c-flag) }

/* The checkbox column. Hidden until the row is reached or the mode is on —
   "selection is a verb", so the affordance arrives when it is wanted. */
.c-list .c-pick { width: 34px; padding-right: 2px }
.c-list .c-pick input { opacity: 0; margin: 0; cursor: pointer; accent-color: var(--c-beam) }

.c-list tbody tr:hover .c-pick input,
.c-list tbody tr:focus-within .c-pick input,
.c-list tbody tr:focus-visible .c-pick input,
.c-list.picking .c-pick input { opacity: 1 }

/*
 * A HEADER THAT SORTS IS A BUTTON.
 *
 * Not a `th` with a click handler: that is unreachable by keyboard,
 * unannounced by a screen reader and undiscoverable to anybody who has not
 * already guessed. Sans and quiet, because a column header is furniture — the
 * mark beside it is what carries the state.
 */
.c-list .c-colsort {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  color: var(--c-ink-2);
}

.c-list .c-colsort:hover { color: var(--c-ink) }
.c-list .c-colsort.on { color: var(--c-ink) }
.c-list .c-colsort:focus-visible { outline: 2px solid var(--c-beam); outline-offset: 3px }

/* Drawn at rest on the active column, not on hover — hover does not exist on a
   phone, and is not an affordance on a mouse until you are already pointing at
   the thing you were meant to find. */
.c-list .c-colmark {
  width: 0;
  height: 0;
  flex: none;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}

.c-list .c-colmark.asc { border-bottom: 5px solid currentColor }
.c-list .c-colmark.desc { border-top: 5px solid currentColor }
.c-list .c-colmark.off { border-bottom: 5px solid currentColor; opacity: .22 }
.c-list .c-colsort:hover .c-colmark.off { opacity: .5 }

/* A control inside the selection capsule. B's `.seltool > button`, verbatim. */
.c-seltool-btn {
  background: none;
  border: 0;
  color: #C9C4D4;
  cursor: pointer;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--c-r-sm);
  padding: 0;
}

.c-seltool-btn:hover:not([disabled]) { background: var(--c-frame-2); color: #fff }
.c-seltool-btn[disabled] { opacity: .4; cursor: default }

/*
 * A select inside a row — the rescue control on unfiled work.
 *
 * The one form control B has no shape for, because a document editor has no
 * forms. Built from the note's own surface and hairline rather than invented:
 * paper ground, `--c-note-line` edge, sans at the chrome size.
 */
.c-list .c-filepick {
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  color: var(--c-ink);
  background: #FFFDF9;
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-sm);
  padding: 5px 9px;
  max-width: 15rem;
  cursor: pointer;
}

.c-list .c-filepick:focus-visible { outline: 2px solid var(--c-beam); outline-offset: 2px }
.c-list .c-filepick[disabled] { opacity: .5; cursor: default }

/* A secondary line under a value. It was mono on the claim that it is "always
   a format or an identity rather than a phrase", and the call sites say
   otherwise: "Ranked from what the account actually has, not from an order
   somebody typed", "none changed since we read them", "Measured on this
   account, against a source you can go and read". Phrases, all of them, and
   under a section heading rather than under a value. Sans at the chrome size;
   8.5px was a mono's size and is unreadable in a sans. */
.c-list .c-sub {
  display: block;
  font-family: var(--c-sans);
  font-size: var(--c-ui-xs);
  color: var(--c-meta);
  margin-top: 3px;
}

/* The paper a table scrolls inside. Seven columns do not fit a phone and the
   page must never scroll sideways — that moves the heading that says where
   you are. */
.c-scroll { overflow: auto; background: var(--c-paper) }
.c-scroll:focus-visible { outline: 2px solid var(--c-beam); outline-offset: -2px }

/* Prose on paper, above or below a list — the empty state, the one-line
   explanation. Held to the mock's measure so a sentence never runs the full
   width of a table. */
.c-prose {
  font-family: var(--c-sans);
  font-size: var(--c-ui);
  line-height: 1.6;
  color: var(--c-ink-2);
  max-width: 68ch;
  margin: 0;
  padding: var(--c-beat-15) var(--c-gap-lg);
}

.c-prose strong { color: var(--c-ink); font-weight: 600 }

/* ==========================================================================
   10. THE SIGNATURE MARK
   ==========================================================================
   The pink squiggle, kept, calmed to 1px. Full crimson stops a release; the
   same squiggle softer needs a person. It fades in over 240ms and NEVER moves
   text — zero layout shift is the whole point of drawing it as a decoration
   rather than an inserted element.
   ========================================================================== */

.c-mark {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: transparent;
  transition: text-decoration-color .24s ease-out;
}

.c-mark.stop { text-decoration-color: var(--c-flag) }
.c-mark.hold { text-decoration-color: var(--c-flag-soft) }

/* ==========================================================================
   11. GROUND RULES
   ========================================================================== */

.calm { font-family: var(--c-sans); color: var(--c-ink) }
.calm *, .calm *::before, .calm *::after { box-sizing: border-box }
.calm :focus-visible { outline: 2px solid var(--c-beam); outline-offset: 2px }
.calm ::selection { background: rgba(11, 117, 111, .16) }

/* WHAT IS LEFT OF THE GOVERNANCE VOICE AFTER 2026-09-16: tabular figures.
   The class used to hand out `--c-mono`, and its call sites are the argument
   against that — whole sentences ("No rule on this brand names this document.
   It is on file and nothing has been drawn from it."), dates, counts, a
   source's kind and version. One identifier among them does not make the
   class an identifier's.
   It keeps the name and it keeps the one thing a record actually needs from
   its type: figures that line up in a column. An id, a revision, a hash or a
   fingerprint takes `--c-mono` at its own call site, and nothing else does. */
.c-gov {
  font-family: var(--c-sans);
  font-variant-numeric: tabular-nums;
}

/* Content voice — the customer's own words, wherever they are the subject. */
.c-doc { font-family: var(--c-serif) }

@media (prefers-reduced-motion: reduce) {
  .calm *, .calm *::before, .calm *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* ==========================================================================
   12. THE MAP — old `mock.css` name -> new calm token or class
   ==========================================================================

   Committed so later waves are mechanical rather than interpretive. A
   conversion that needs a judgement call is a conversion that produces a sixth
   dialect. Where the right-hand column says RESTRUCTURE, there is no
   equivalent and the component's markup has to change — those are the rows
   that matter, and taking the token swap instead is the bandaid this system
   exists to prevent.

   ---- MATERIALS ---------------------------------------------------------
   --paper            #F4F3F6 cool grey   ->  --c-paper       #FBF8F2 warm
   --surface                              ->  --c-paper       (one material)
   --surface-2                            ->  --c-note-bg     where it is a note
   --surface-3                            ->  --c-frame       where it is chrome
   --line / --line-soft                   ->  --c-hairline
   --line-strong                          ->  --c-note-line
   --ink              #17151C             ->  --c-ink         #211D15 warm
   --ink-2                                ->  --c-ink-2
   --ink-3 / --ink-4                      ->  --c-meta
   (no equivalent)                        ->  --c-frame, --c-frame-2,
                                              --c-frame-line, --c-readout,
                                              --c-readout-dim, --c-readout-hi
                                              THE FRAME IS NEW. A surface with
                                              a governance voice gains a plate;
                                              it is not a recoloured band.

   ---- MEANING COLOUR ----------------------------------------------------
   --flag                                 ->  --c-flag        (stops a release)
   --flag-bright                          ->  --c-flag        (one tone, not two)
   --flag-wash                            ->  RESTRUCTURE — B washes nothing.
                                              A finding is a squiggle on the
                                              words plus a margin mark, never a
                                              tinted row.
   --judge / --judge-wash                 ->  --c-flag-soft   (needs a person)
   --beam / --beam-wash                   ->  --c-beam
   --cleared / --cleared-wash             ->  --c-beam        (affirmation is
                                              one colour, not two)
   (any orange)                           ->  DOES NOT EXIST. Standing rule.

   ---- TYPE --------------------------------------------------------------
   --sans / --serif / --mono              ->  --c-sans / --c-serif / --c-mono
   .mono                                  ->  --c-mono ONLY on an identifier:
                                              a revision, a fingerprint, an id,
                                              code, a file name, a key. A count
                                              is not one, a date is not one and
                                              a state word is not one — those
                                              take `.c-gov`, which is the sans
                                              with tabular figures. Everywhere
                                              else this class appears today it
                                              is the violation — see §13.
   .eyebrow      10.5px mono .14em        ->  --c-ui-sm SANS, sentence case.
                                              An eyebrow is wayfinding.
   .tech         12px mono (index.css)    ->  --c-ui-sm SANS wherever it is a
                                              label, a date, a count or a
                                              sentence — which is nearly all of
                                              them; --c-mono only where the
                                              string is an id or a revision.
   .micro        11px                     ->  --c-ui-xs, sans
   h1 / .phead h1                         ->  --c-ui-title
   h2 (screen heading)                    ->  --c-ui-display
   body 16px/1.55                         ->  --c-ui (13.5px) for chrome;
                                              --c-doc (19px/32px) for content.
                                              There is no 16px in B: the split
                                              between furniture and words is
                                              the point.
   .lede                                  ->  --c-ui-lg
   .doc (serif 19px/1.85)                 ->  --c-doc / --c-lh-doc (19/32)

   ---- SPACING -----------------------------------------------------------
   .bandh margin 14px                     ->  --c-beat-15   (48px) BETWEEN BANDS
   .pagehead padding                      ->  --c-beat-open (60px) above
   section gap 16-20px                    ->  --c-beat-15   (48px)
   heading to body 8px                    ->  --c-beat-125  (40px)
   .wrap max-width 1120px                 ->  --c-measure   (620px) for content;
                                              a table keeps its own width, but
                                              the prose above it does not.
   ad-hoc marginTop: 20 (workViews)       ->  --c-beat-15
   ad-hoc gap 8/10/11px                   ->  --c-gap-sm / --c-gap / --c-gap-md

   ---- ELEVATION ---------------------------------------------------------
   --shadow-2                             ->  --c-e-note
   --shadow-3                             ->  --c-e-menu
   (no equivalent)                        ->  --c-e-instrument, --c-e-seltool
   --r-sm / --r / --r-lg                  ->  --c-r-sm / --c-r / --c-r-lg

   ---- CONTROLS ----------------------------------------------------------
   .ico   16px stroke 1.6                 ->  .c-ico  15px stroke 1.5
   .ico.s 13px                            ->  .c-ico.sm 13px
   .btn / .btn.sm / .btn.pri              ->  RESTRUCTURE. B has no button row.
                                              A primary act is one verb; every
                                              secondary command moves into
                                              .c-menu; anything icon-shaped
                                              becomes .c-iconbtn WITH A TIP.
   .btn.gh (borderless)                   ->  .c-iconbtn or a .c-menu item.
                                              A borderless text button reads as
                                              a caption — already reported.
   .pill  (uppercase chip)                ->  RESTRUCTURE. B carries state in
                                              the status sentence and the
                                              squiggle, not in chips. Where a
                                              per-row state word survives it is
                                              sans at --c-ui-sm, sentence case.
   .callout / .callout.stop               ->  the .c-status sentence, or a
                                              .c-note beside the thing
   .switcher                              ->  .c-plate .c-crumb + .c-menu
   .inp                                   ->  RESTRUCTURE toward .c-capsule
                                              shape; a filter field on a plate
                                              is chrome, not a form.
   .wselbar (bulk bar)                    ->  .c-seltool.floating
   .wfilters (toolbar row)                ->  .c-plate
   .wcount / "N shown"                    ->  .c-status .c-aux
   .wlistwrap                             ->  .c-paper inside .c-instrument
   .colsort / .colmark                    ->  kept: sorting logic and markers
                                              are correct already. Restyled by
                                              living inside .c-paper.

   ---- BEHAVIOUR ---------------------------------------------------------
   (nothing)                              ->  .c-recede + .c-chrome on every
                                              surface with a primary act
   title="..." on an icon                 ->  data-tip + aria-label, via
                                              <IconButton>. A bare title never
                                              appears on a touch device.

   ==========================================================================
   13. THE TYPE-ROLE RULE, WHERE IT IS BROKEN TODAY
   ==========================================================================
   Recorded here rather than in a note, so a later wave converting one of these
   surfaces finds it at the moment it is looking at the stylesheet. Each is mono
   doing the job of sans — furniture wearing the record's voice.

   THE RULE THIS AUDIT IS MEASURED AGAINST NARROWED ON 2026-09-16. It was
   "governance is mono"; it is now "an IDENTIFIER is mono" — a revision, a
   fingerprint, an id, code, a file name, a key sequence, and nothing else.
   Every entry below still stands, and the list at the foot is shorter than it
   was, because a count and a date went with the rest.

   THE THREE WORST, in order of how much they cost:

   1. `.eyebrow` — mock.css:94 and mock.css:814 (the scoped one wins in the
      shell). Call site `parts.tsx:102`, inside `PageHead`, which 39 SCREENS
      use. Its own doc comment says what it is: "what this screen is, in one
      word, always in the same slot" — a wayfinding label, the definition of
      furniture. Because it sits top-left of every signed-in screen, mono is
      the first thing the eye meets everywhere, so by the time a real readout
      appears the voice has already been spent. Worst offender by reach.

      The same class is also used for whole SENTENCES, which is louder still:
      `WhileYouWereAway.tsx:247`, `workViews.tsx:292`, `Rules.tsx:1831`
      ("N suggestions from what these rules have actually done"),
      `Signals.tsx:1144`, and on a `<label>` at `Profile.tsx:126`.
      -> convert to sans at --c-ui-sm; keep the slot, drop the face.

   2. `.tech` — index.css:1147, the utility form of `TYPE.tech`. Two live
      violations under one class:
        a. THE COPY HEADER'S FOUR MONO LINKS, named in the directive:
           `CopyStudio.tsx:2474` "live", `:2478` "where this came from",
           `:2481` "revisions", `:2491` "comments". These are four
           panel-opening controls — the studio's navigation bar wearing the
           governance face. index.css:338 admits it: "the header actions are
           `.tech` labels with no border until hover".
        b. BREADCRUMB NAVIGATION: `system.tsx:324`, `:330`, and the `›`
           separator at `:319`, riding on ~38 pages.
      -> both become sans. `.tech`'s other ~441 sites were called LEGITIMATE
         here on the old rule; on the new one only the revisions and the ids
         among them are, and the counts and the dates are the same defect at
         lower volume. Still a call-site conversion rather than a class-wide
         one — but the class is now wrong far more often than it is right.

   3. `.advicego` — mock.css:1368. Row call-to-action labels: `Desk.tsx:930`
      "Open", `Rules.tsx:1770` "Needs a person" / "Removes N",
      `Signals.tsx:1159` "Read it" / "See the rules" / "Bring it in",
      `rulesPerformance.tsx:150` "Open it". Verb phrases ending in a drawn
      chevron — the purest chrome element there is — set in beam-coloured
      mono. The same fault repeats in `.seeall` (mock.css:1196), `.ncgo`
      (:853) and `.staffgo` (:1560), which are three classes drawing one
      thing: a navigation link with an arrow.
      -> sans, and fold the four classes into one.

   ALREADY FIXED, here, in Wave 1: `.mockroot th` (mock.css:444) set every
   table column header in mono. `.c-list thead th` sets them in sans, sentence
   case. The codebase already contradicted itself on this one — `system.tsx:227`
   defines `TYPE.micro` as sans and documents it as "column headers and state
   vocabulary ONLY".

   LEGITIMATE, for contrast — do not convert: `.mark-cite` (index.css:604),
   which is a rule's identity, and every `.tech` carrying a revision or an id.
   These are strings a person reads character by character, which is what mono
   is FOR. `TYPE.figure` (system.tsx:213) and `.regkind` (mock.css:1508) were
   on this list and are OFF it: a figure is a count and a kind is a word.
   `.raillink em` goes to whichever half of it is true at the call site.
   ========================================================================== */

/* ==========================================================================
   12. THE PLATFORM SURFACE — `platform-rules.html`, lifted
   ==========================================================================

   Source: `docs/superpowers/mockups/platform-rules.html`. Sections 1–11 above
   are Direction B as the STUDIOS speak it (`direction-b-instrument.html`);
   this is Direction B at PLATFORM scale, and the two mocks share a `:root`
   block to the byte — which is why §4b needed only six new tokens and this
   section needs no new colour at all.

   THE METHOD, AND IT IS NOT A SUGGESTION (spec §4a). Every declaration below
   was copied out of that file's `<style>` block: same selectors, same nesting,
   same property order, same values. Where a number here differs from the mock,
   that is a defect in this file and not a decision.

   THE ONLY MECHANICAL CHANGE, and it is the same one §1 made: class names are
   prefixed `c-` and tokens `--c-`, because `mock.css` already owns `.btn`,
   `.chip`, `.tick`, `.callout`, `.quote`, `.spark`, `.srcline` and `.prov`
   globally in `@layer components`. Four names could not take a bare prefix
   because §§1–11 had already spent them on a different object, and each is
   noted where it appears:

       mock `.mk`      -> `.c-mark`    (ported in §10 — reused, not redrawn)
       mock `.seltool` -> `.c-seltool` (ported in §8  — reused, not redrawn)
       mock `.mark`    -> `.c-gut`     (the gutter tick; `.c-mark` is the squiggle)
       mock `.sel`     -> `.c-select`  (the <select>; `.sel` is the checkbox cell)

   Nothing else was adapted, rounded, or improved.
   ========================================================================== */

/* ---- the readout voice, and it is no longer a typeface -------------------
   This was "the only door mono comes through", and the door turned out to
   open onto furniture. Every call site, read one by one: "3 of 12" on a rack,
   "still to do", "Set aside", "Suspended — no reason recorded", "Finding the
   brand to read coverage for…", "Coverage is read per brand, and this account
   has none yet", and the eyebrow over the setup checklist. Counts, labels,
   eyebrows and sentences — not one identifier among them, and all of it in
   uppercase mono at .13em across the platform surfaces.

   So the readout keeps its job, which is to be quieter and steadier than the
   thing it sits beside, and gives up the face. Sans, sentence case, tabular
   figures for the counts. The law it carried is unchanged and simply narrower
   now: mono on a calm surface means an identifier — a revision, a
   fingerprint, an id, code — and arrives at the one element that holds one. */
.c-ro {
  font-family: var(--c-sans);
  font-size: var(--c-ui-sm);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}
/* a sentence rather than a fact: the same voice with room to breathe */
.c-ro.lc { font-size: var(--c-ui-md) }
.c-ro.sm { font-size: var(--c-ui-xs) }

/*
 * THE CANVAS — the warm ground the work sits on.
 *
 * The mock's `.canvas { background: var(--paper) }`. Without it a rack renders
 * as a near-white card on a near-white page and the two-material idea — warm
 * paper held inside a graphite instrument — is invisible: measured in Chrome,
 * `#FFFDF9` on `#F4F3F6`, which is not a card, it is a rectangle.
 *
 * On the app it goes on the CONTENT column rather than on the whole shell,
 * because the shell (`platform-shell-desk.html`) is its own conversion and the
 * rail belongs to it. That leaves one seam, at the rail's hairline, and it is
 * the shell's to close.
 */
.c-canvas { background: var(--c-paper); min-height: 100% }

/*
 * THE MEASURE — the mock's `.wrap`, verbatim.
 *
 *     .wrap { max-width: 1060px; margin: 0 auto; padding: 36px 30px 110px }
 *
 * Left out of the first pass and caught in the side-by-side: the converted
 * screen ran the full 1154px content column with zero padding, which is the
 * "close enough spacing" failure mode by name — every column sat further right
 * than the mock's and the rack touched both edges of the canvas. The 110px
 * foot is what lets the last row breathe above the fold.
 */
.c-wrap { max-width: 1060px; margin: 0 auto; padding: 36px 30px 110px }

@media (max-width: 900px) { .c-wrap { padding: 26px 16px 120px } }

/* ---- the page head ------------------------------------------------------ */
.c-pagehead { margin: 0 0 var(--c-gap-section) }
.c-pagehead .c-eyebrow {
  color: var(--c-meta);
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
/*
 * THE EYEBROW IS QUIET; ANYTHING PRESSABLE INSIDE IT IS A CONTROL.
 *
 * This used to read "mono is a door, not a font — and a button is not walking
 * through it", which was the same distinction drawn with a typeface: the
 * eyebrow carried `.c-ro` and the button had to take the sans back. `.c-ro` is
 * sans now, so the door is gone and the distinction is not: the control states
 * its own size, weight, ground and border, because in the mock that is what a
 * `.btn` does and the app's own help control does not.
 */
.c-pagehead .c-eyebrow button,
.c-pagehead .c-eyebrow a {
  /* the mock's own control, inline:
     <button class="btn sm" style="margin-left:6px;padding:3px 9px;font-size:11px"> */
  font-family: var(--c-sans);
  text-transform: none;
  letter-spacing: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--c-ink);
  background: var(--c-card);
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-sm);
  padding: 3px 9px;
  margin-left: 6px;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.c-pagehead .c-eyebrow button:hover,
.c-pagehead .c-eyebrow a:hover { border-color: #B9B3C6 }
.c-pagehead .c-eyebrow i {
  width: 6px;
  height: 6px;
  background: var(--c-beam);
  border-radius: 2px;
  display: block;
  flex: none;
}
.c-pagehead h1 {
  font-family: var(--c-sans);
  font-size: 27px;
  font-weight: 600;
  letter-spacing: -.022em;
  margin: 0 0 9px;
  color: var(--c-ink);
}
.c-pagehead p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--c-ink-2);
  max-width: 66ch;
}

/* sections breathe: 56px between them, and a hairline that ends each one */
.c-section { margin: 0 0 var(--c-gap-section); scroll-margin-top: 20px }
.c-section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0 0 20px;
  padding-bottom: 11px;
  border-bottom: 1px solid var(--c-hairline);
  flex-wrap: wrap;
}
.c-section-head h2 {
  font-family: var(--c-sans);
  font-size: 16.5px;
  font-weight: 600;
  letter-spacing: -.012em;
  margin: 0;
  color: var(--c-ink);
}
.c-section-head .c-sub { font-size: 12.5px; color: var(--c-ink-2) }
.c-section-head .c-rhs {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  position: relative;
}
.c-lede {
  margin: 0 0 var(--c-gap-block);
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--c-ink-2);
  max-width: 68ch;
}

/* the triage figures. Mono is legal on the LABEL because a triage count is a
   readout; the number itself is sans and calm — a zero is affirmation, never
   grey, and never an alarm. */
.c-figs { display: flex; gap: 36px; flex-wrap: wrap; margin: 24px 0 0 }
.c-fig .n {
  font-family: var(--c-sans);
  font-size: 27px;
  font-weight: 500;
  letter-spacing: -.03em;
  line-height: 1;
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
  display: block;
}
.c-fig .n.stop { color: var(--c-flag) }
.c-fig .n.hold { color: #A8437C }
.c-fig .n.clear { color: var(--c-beam) }
.c-fig .n.mut { color: var(--c-ink-2) }
.c-fig .o {
  margin-top: 9px;
  color: var(--c-meta);
  max-width: 16ch;
  display: block;
  line-height: 1.45;
}

/* a state tag. SANS, because a chip is chrome; three tones, because there are
   three states with meaning. The product's mono IN FORCE chips are named
   defect 4 in the directive, and this is the conversion. */
.c-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--c-sans);
  font-size: 11px;
  font-weight: 600;
  color: var(--c-ink-2);
  background: none;
  border: 1px solid var(--c-hairline);
  border-radius: 999px;
  padding: 3px 9px;
  white-space: nowrap;
}
.c-tag.stop { color: var(--c-flag); border-color: rgba(214, 0, 110, .32); background: var(--c-flag-wash) }
.c-tag.hold { color: #9A3D6E; border-color: rgba(228, 137, 182, .48); background: #FDF4F8 }
.c-tag.clear {
  color: var(--c-beam);
  border-color: rgba(11, 117, 111, .28);
  background: rgba(11, 117, 111, .06);
}
.c-tag.mut { color: var(--c-meta) }
/*
 * A TAG THAT IS A BUTTON LOOKS PRESSABLE AND IS. A TAG THAT IS NOT, IS NOT.
 *
 * The mock's severity control is `<button class="tag stop">` — the label IS
 * the answer rather than a colour to decode. That leaves a `<span class="tag">`
 * sitting beside a visually identical `<button class="tag">`, which is the
 * "looks like a control and isn't" defect by construction. So a pressable tag
 * takes the hand and a border on hover; a refused one keeps the border and
 * says why in its accessible name rather than going quiet.
 */
button.c-tag { cursor: pointer }
button.c-tag:hover:not([aria-disabled='true'], [disabled]) { border-color: var(--c-ink-2) }
button.c-tag.stop:hover:not([aria-disabled='true'], [disabled]) { border-color: var(--c-flag) }
button.c-tag[aria-disabled='true'], button.c-tag[disabled] { cursor: not-allowed }

/* a callout states a fact in place. An empty state is NEVER `.stop` — the
   product drew "this brand has no rules yet" in blocking magenta once, which
   told a new customer their first screen was on fire. */
.c-callout {
  background: var(--c-note-bg);
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-card);
  padding: 16px 18px;
  margin: 0 0 var(--c-gap-block);
}
.c-callout .ct {
  font-family: var(--c-sans);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--c-ink);
  margin: 0 0 7px;
}
.c-callout p { margin: 0; font-size: 13px; line-height: 1.62; color: var(--c-ink-2) }
.c-callout p + p { margin-top: 9px }
.c-callout ul {
  margin: 9px 0 0;
  padding-left: 17px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--c-ink-2);
}
.c-callout li { margin-bottom: 7px }
.c-callout .acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 13px; align-items: center }
.c-callout.stop { background: var(--c-flag-wash); border-color: #F0D3E1 }
.c-callout.stop .ct { color: var(--c-flag) }
.c-callout.hold { background: #FDF4F8; border-color: #F2DCE8 }

/* THE SECOND (AND LAST) LIST SHAPE. Where a table is genuinely wrong — advice,
   packs, the sources of a nav, tasks — every list in the product is this. Two
   shapes total, against the six bespoke ones named in complaint 1. */
.c-rowlist {
  border: 1px solid var(--c-hairline);
  border-radius: var(--c-r-card);
  background: var(--c-card);
  overflow: hidden;
}
.c-row2 {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 17px;
  border-bottom: 1px solid rgba(33, 29, 21, .07);
  text-decoration: none;
  color: inherit;
  width: 100%;
  text-align: left;
  background: none;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  font-family: var(--c-sans);
  cursor: pointer;
}
.c-row2:last-child { border-bottom: 0 }
.c-row2:hover { background: rgba(33, 29, 21, .028) }
.c-row2 > .m { min-width: 0; flex: 1 }
.c-row2 .t { font-size: 13.5px; font-weight: 600; color: var(--c-ink); display: block }
.c-row2 .w {
  font-size: 12.5px;
  color: var(--c-ink-2);
  display: block;
  margin-top: 4px;
  line-height: 1.55;
}
.c-row2 .c {
  margin-left: auto;
  flex: none;
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--c-meta);
}
.c-row2 .go { color: var(--c-beam); display: flex; align-items: center; gap: 6px }
.c-row2 .c-ico { color: var(--c-meta); flex: none }
/* A ROW THAT IS NOT A DOOR MUST NOT DRAW ITSELF AS ONE. The panel's precedent
   entries are `<div class="row2">` in the mock — the same shape, with nothing
   to press — so they lose the hand and the hover that the pressable ones have. */
div.c-row2 { cursor: default }
div.c-row2:hover { background: none }
/* THE CITATION, on the one widget obliged to carry one. Same size as the
   sentence it backs, and separated by a rule rather than shrunk: a source drawn
   as fine print is a source nobody checks, and a Desk item that cannot be
   checked is the unattributed statistic this product exists to catch, printed
   by us on our own home screen. `--c-ink-2` is 5.54:1 on the card. */
.c-row2 .src {
  display: block;
  margin-top: 9px;
  padding-top: 8px;
  border-top: 1px solid var(--c-hairline);
  font-size: 12px;
  line-height: 1.55;
  color: var(--c-ink-2);
}

/* ---- controls ----------------------------------------------------------- */
.c-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--c-sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--c-ink);
  background: var(--c-card);
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-sm);
  padding: 7px 13px;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.c-btn:hover { border-color: #B9B3C6 }
.c-btn.primary { background: var(--c-frame); border-color: var(--c-frame); color: var(--c-readout-hi) }
.c-btn.primary:hover { background: var(--c-frame-2); border-color: var(--c-frame-2) }
.c-btn.sm { font-size: 12px; padding: 5px 10px; gap: 6px }
/*
 * DISABLED IS A COLOUR, NOT A FILTER.
 *
 * `opacity` composites the label and the ground it sits on toward the page at
 * the same rate, so a primary button — white on ink — lands at roughly 2.6:1
 * and reads as grey-on-grey. Screen-verified on /app/start, where "Next" is
 * disabled until the brand is named: the first control a new account meets.
 *
 * A disabled control still has to be READ. It is unavailable, not absent, and
 * the person has to see what it will say when it turns on.
 */
.c-btn[disabled], .c-btn[aria-disabled='true'] { opacity:1; cursor:not-allowed;
  background:var(--surface-3); border-color:var(--line);
  color:var(--ink-3); box-shadow:none; }
.c-btn[disabled]:hover { border-color: var(--c-note-line) }

.c-select {
  font-family: var(--c-sans);
  font-size: 12.5px;
  color: var(--c-ink);
  background: var(--c-card);
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-sm);
  padding: 6px 9px;
  cursor: pointer;
}
.c-fld {
  font-family: var(--c-sans);
  font-size: 13px;
  color: var(--c-ink);
  background: var(--c-card);
  border: 1px solid var(--c-note-line);
  border-radius: var(--c-r-sm);
  padding: 8px 11px;
  width: 100%;
}
.c-fld::placeholder { color: var(--c-meta) }
.c-lab {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-ink-2);
  margin: 0 0 6px;
}
.c-hint { font-size: 12px; line-height: 1.55; color: var(--c-ink-2); margin: 6px 0 0 }

/* a two-state control that says what it is, not "on" */
.c-swt {
  position: relative;
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: rgba(33, 29, 21, .16);
  border: 0;
  cursor: pointer;
  padding: 0;
  flex: none;
  transition: background .14s ease-out;
}
.c-swt::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--c-lift-1);
  transition: transform .14s ease-out;
}
.c-swt[aria-checked='true'] { background: var(--c-beam) }
.c-swt[aria-checked='true']::after { transform: translateX(16px) }
.c-swt[disabled] { opacity: .4; cursor: not-allowed }

.c-cardbox {
  background: var(--c-card);
  border: 1px solid var(--c-hairline);
  border-radius: var(--c-r-card);
  padding: 20px 22px;
}
.c-kv {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 9px 20px;
  font-size: 13px;
  margin: 0;
}
.c-kv dt { color: var(--c-ink-2) }
.c-kv dd { margin: 0; color: var(--c-ink) }

/* a fact the record supplies, quoted rather than paraphrased */
.c-quote {
  font-family: var(--c-serif);
  font-size: 14px;
  line-height: 1.6;
  color: #4A4655;
  border-left: 2px solid var(--c-note-line);
  padding-left: 14px;
  margin: 0;
}
/* #847E92 in the mock, which is 3.84:1 on the card — under AA for a 9px line
   that names a source. Darkened along its own hue to 5.03:1. */
.c-prov { color: #716B7F; display: flex; align-items: center; gap: 7px; flex-wrap: wrap }

/* THE GUTTER TICK — the squiggle's reading where the row's subject is not its
   words. `.c-mark` in §10 is the squiggle itself; this is the same meaning
   drawn as a short rule in the margin. (Mock: `.mark`.) */
.c-gut {
  width: 15px;
  height: 0;
  border-top: 2px solid transparent;
  display: block;
  flex: none;
}
.c-gut.stop { border-top-color: var(--c-flag) }
.c-gut.hold { border-top-color: var(--c-flag-soft) }
/* A rule that catches nothing. Ink, not the flag: it is worth surfacing and it
   is not an alarm, and the flag colour means a finding that stops a release. */
.c-gut.gap { border-top-color: var(--c-readout, #6b6579) }
.c-gut.clear { border-top-color: rgba(33, 29, 21, .16) }

/* ==========================================================================
   12b. THE RACK — the one list primitive
   ==========================================================================

   Serves Rules, People, Brands, Releases, Work and Drafts. Rows differ only in
   what a cell SAYS. Named complaint 1: six bespoke lists become one chassis.

   Sortable columns, a filter bar, selection with shift-range, a bulk command
   bar that is the SAME graphite surface as the studios' text-selection toolbar
   (§4b: a user must not be able to tell which surface they are on by looking
   at it — so `.c-seltool` from §8 is reused rather than redrawn), keyboard
   complete, capability-aware — a seat that cannot act gets NO selection column
   at all, rather than a checkbox that refuses.
   ========================================================================== */

.c-rack {
  border: 1px solid var(--c-hairline);
  border-radius: var(--c-r-card);
  background: var(--c-card);
  position: relative;
}

.c-rack-tools {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-hairline);
  flex-wrap: wrap;
}
.c-rack-find {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--c-paper);
  border: 1px solid var(--c-hairline);
  border-radius: 999px;
  padding: 6px 13px;
  flex: 0 1 280px;
  min-width: 180px;
}
.c-rack-find:focus-within { border-color: #B9B3C6 }
.c-rack-find .c-ico { color: var(--c-meta) }
.c-rack-find input {
  border: 0;
  background: none;
  outline: none;
  font-family: var(--c-sans);
  font-size: 13px;
  color: var(--c-ink);
  width: 100%;
}
.c-rack-find input::placeholder { color: var(--c-meta) }
.c-rack-filters { display: flex; align-items: center; gap: 5px; flex-wrap: wrap }

.c-chip {
  font-family: var(--c-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--c-ink-2);
  background: none;
  border: 1px solid var(--c-hairline);
  border-radius: 999px;
  padding: 5px 11px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.c-chip:hover { border-color: var(--c-meta); color: var(--c-ink) }
.c-chip.on { background: var(--c-frame); border-color: var(--c-frame); color: var(--c-readout-hi) }
.c-chip .n { color: var(--c-meta) }
.c-chip.on .n { color: var(--c-beam-frame) }
.c-chip .c-gut { width: 12px }

/*
 * The count is the instrument speaking a sentence, so it takes `.c-ro.lc` —
 * the roomier of the two readout sizes. It was on screen at 10.5px/.13em
 * uppercase mono once, where "7 of 7" rendered as "7 0F 7": the mono zero and
 * the capital O are one glyph apart and the tracking pulled the F off the O.
 * That defect is now impossible rather than corrected — `.c-ro` has neither
 * the caps nor the tracking, and "7 of 7" is seven, of, seven.
 */
.c-rack-count {
  margin-left: auto;
  color: var(--c-meta);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 9px;
}

/* NO overflow by default. `overflow-x:auto` computes `overflow-y:auto` too, and
   that clips every tooltip and every row menu inside the table — the two
   affordances a row's "…" button exists for. Only a table that is genuinely a
   matrix carries `.wide`, and those have no row menus, so nothing is ever
   clipped that a person needed. */
.c-rack-scroll.wide { overflow-x: auto }

/*
 * THE LIFT HAS TO STAND ON ITS OWN, AND THIS IS WHERE IT DID NOT.
 *
 * Found in Chrome, not by a test. `mock.css` styles bare elements under
 * `.mockroot` — `th` in 9.5px uppercase mono, `td` with its own padding and a
 * border, `table` with a 14px margin — and a rack rendered inside that subtree
 * inherits all of it wherever this block is SILENT. Layer order saves the
 * declarations that exist here (unlayered beats `@layer components` whatever
 * the specificity); it cannot save the ones that do not.
 *
 * So the properties `platform-rules.html` never had to state — because its own
 * page has no global table styling — are stated here. Every value below is the
 * mock's rendered value, not a new decision: the head is the `.rack-sort`
 * face, the cell is `.rack-cell`, and the borders are the row's, once.
 */
.c-rack-grid { width: 100%; border-collapse: collapse; margin: 0 }
.c-rack-grid th, .c-rack-grid td { text-align: left; vertical-align: middle }
.c-rack-th {
  padding: 0;
  border-bottom: 1px solid var(--c-hairline);
  white-space: nowrap;
  background: var(--c-card);
  position: sticky;
  top: 0;
  z-index: 3;
  /* what the mock's page never had to say */
  font-family: var(--c-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .035em;
  text-transform: none;
  color: var(--c-ink-2);
}
.c-rack-sort {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: none;
  border: 0;
  font-family: var(--c-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .035em;
  color: var(--c-ink-2);
  padding: 12px 14px;
  cursor: pointer;
  white-space: nowrap;
}
.c-rack-sort:hover { color: var(--c-ink) }
.c-rack-sort .car {
  opacity: 0;
  transition: opacity .12s ease-out, transform .12s ease-out;
  color: var(--c-beam);
}
.c-rack-th[aria-sort='ascending'] .c-rack-sort,
.c-rack-th[aria-sort='descending'] .c-rack-sort { color: var(--c-ink) }
.c-rack-th[aria-sort='ascending'] .car,
.c-rack-th[aria-sort='descending'] .car { opacity: 1 }
.c-rack-th[aria-sort='descending'] .car { transform: rotate(180deg) }
.c-rack-th.num .c-rack-sort { justify-content: flex-end }
.c-rack-th.static {
  padding: 12px 14px;
  font-family: var(--c-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .035em;
  color: var(--c-ink-2);
}
.c-rack-th.sel { width: 40px; padding: 0 0 0 15px }

/* `background-color`, not `background` — the shorthand would wipe the texture
   rails below, which are drawn with background-image on the same element. */
.c-rack-row { border-bottom: 1px solid rgba(33, 29, 21, .07); outline-offset: -2px }
.c-rack-row:last-of-type { border-bottom: 0 }
.c-rack-row:hover { background-color: rgba(33, 29, 21, .028) }
.c-rack-row[data-sel='1'] { background-color: rgba(11, 117, 111, .055) }
.c-rack-row[data-sel='1']:hover { background-color: rgba(11, 117, 111, .078) }
.c-rack-row.open { background-color: rgba(33, 29, 21, .03) }

/* THREE ROW TEXTURES, IN INK. A row can carry a kind that is not a state —
   where a rule came from, where a seat came from — and it must not steal a
   state colour to say so. The product draws provenance in `beam` and `judge`,
   which mean affirmation and attention everywhere else; here it is texture
   only, and the page decides what each texture means. */
/* drawn on the row's FIRST CELL rather than on the row: a `tr` background is
   painted under the cells and a collapsed border eats it. */
.c-rack-row[class*='tex-'] > :first-child {
  background-repeat: no-repeat;
  background-size: 2px 100%;
  background-position: left top;
}
.c-rack-row.tex-solid > :first-child {
  background-image: linear-gradient(rgba(33, 29, 21, .42), rgba(33, 29, 21, .42));
}
.c-rack-row.tex-dash > :first-child {
  background-image: repeating-linear-gradient(180deg,
    rgba(33, 29, 21, .42) 0 7px, transparent 7px 12px);
}
.c-rack-row.tex-fine > :first-child {
  background-image: repeating-linear-gradient(180deg,
    rgba(33, 29, 21, .42) 0 3px, transparent 3px 6px);
}
/* the same three textures as a legend swatch */
.c-tex {
  width: 3px;
  height: 15px;
  display: block;
  flex: none;
  border-radius: 1px;
  background-repeat: no-repeat;
  background-size: 3px 100%;
}
.c-tex.solid { background-image: linear-gradient(rgba(33, 29, 21, .38), rgba(33, 29, 21, .38)) }
.c-tex.dash {
  background-image: repeating-linear-gradient(180deg,
    rgba(33, 29, 21, .38) 0 5px, transparent 5px 8px);
}
.c-tex.fine {
  background-image: repeating-linear-gradient(180deg,
    rgba(33, 29, 21, .38) 0 2px, transparent 2px 4px);
}

.c-rack-cell {
  padding: 14px;
  font-size: 13.5px;
  color: var(--c-ink);
  line-height: 1.45;
  /* the row draws the rule, once — see the note above `.c-rack-grid` */
  border: 0;
  vertical-align: middle;
  text-transform: none;
  letter-spacing: normal;
}
.c-rack-cell.sel { padding: 0 0 0 15px; width: 40px }
.c-rack-cell.num { text-align: right; color: var(--c-ink-2); white-space: nowrap }
/* `position:relative` or a row menu hangs off the page rather than off the row. */
.c-rack-cell.act {
  width: 1%;
  white-space: nowrap;
  padding: 8px 10px 8px 0;
  text-align: right;
  position: relative;
}
.c-rack-name {
  font-family: var(--c-sans);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--c-ink);
  display: block;
  text-decoration: none;
}
a.c-rack-name:hover { text-decoration: underline; text-underline-offset: 3px }
.c-rack-sub { display: block; font-size: 12px; color: var(--c-ink-2); margin-top: 4px }
.c-rack-line { display: flex; align-items: center; gap: 9px }
.c-rack-dim { color: var(--c-ink-2) }
.c-rack-detail > td {
  padding: 2px 16px 24px 55px;
  background: rgba(33, 29, 21, .022);
  border-bottom: 1px solid rgba(33, 29, 21, .07);
}
.c-rack-empty { padding: 52px 22px; text-align: center; color: var(--c-ink-2); font-size: 13.5px }
.c-rack-empty b { display: block; font-size: 15px; color: var(--c-ink); margin-bottom: 7px; font-weight: 600 }
.c-rack-empty .c-btn { margin-top: 16px }
.c-rack-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-top: 1px solid var(--c-hairline);
  color: var(--c-meta);
}
.c-rack-foot .c-btn { margin-left: auto }

/* selection is a verb: acting on a thing starts by selecting it */
.c-tick {
  appearance: none;
  -webkit-appearance: none;
  width: 15px;
  height: 15px;
  border: 1.5px solid var(--c-meta);
  border-radius: 4px;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  flex: none;
  margin: 0;
  position: relative;
}
.c-tick:hover { border-color: var(--c-ink-2) }
.c-tick:checked, .c-tick:indeterminate { background: var(--c-beam); border-color: var(--c-beam) }
.c-tick:checked::after {
  content: '';
  width: 7px;
  height: 4px;
  border-left: 1.7px solid #fff;
  border-bottom: 1.7px solid #fff;
  transform: rotate(-45deg) translate(1px, -1.5px);
}
.c-tick:indeterminate::after { content: ''; width: 8px; height: 0; border-bottom: 1.7px solid #fff }
.c-tick[disabled] { opacity: .5; cursor: not-allowed }

/* ==========================================================================
   12c. RULES' OWN CARGO — the parts only this surface has
   ========================================================================== */

/* a rule's own sentence, wherever it is quoted. The customer wrote it, so it
   is serif, and the squiggle under it means exactly what it means everywhere
   else in the product: full tone stops a release. */
.c-stmt {
  font-family: var(--c-serif);
  font-size: 14.5px;
  line-height: 1.52;
  color: var(--c-ink);
  display: block;
  text-decoration: none;
}
a.c-stmt:hover {
  text-decoration: underline;
  text-decoration-color: var(--c-meta);
  text-underline-offset: 4px;
}
.c-stmt.off { text-decoration: line-through; text-decoration-color: var(--c-meta) }
.c-srcline {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 6px;
  color: var(--c-meta);
  flex-wrap: wrap;
}
.c-srcline b { color: var(--c-ink-2); font-weight: 600 }

/* the effect readout: what this rule has actually done. A distribution, not a
   time series — the bars are a shape, and the number beside them is the fact. */
.c-spark { display: flex; align-items: flex-end; gap: 2px; height: 14px }
.c-spark i { width: 3px; border-radius: 1px; background: var(--c-hairline); display: block }
.c-spark i.lit { background: var(--c-flag-soft) }

/* the owner's editor, folded under a house rule */
.c-edit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 16px 20px;
  margin: 4px 0 0;
}
.c-edit .wide { grid-column: 1 / -1 }
.c-edit textarea {
  font-family: var(--c-serif);
  font-size: 14px;
  line-height: 1.5;
  min-height: 74px;
  resize: vertical;
}
.c-roles { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px }

/* IMPORT — the door. It breathes on its own so it reads as a place to put
   something down, not as a button that got fat. */
.c-droptar {
  border: 1.5px dashed var(--c-note-line);
  border-radius: var(--c-r-card);
  background: linear-gradient(160deg, rgba(11, 117, 111, .04), var(--c-card) 55%);
  padding: 46px 34px;
  text-align: center;
  cursor: pointer;
  display: block;
  width: 100%;
  font-family: var(--c-sans);
  animation: c-breathe-edge 3.6s ease-in-out infinite;
}
@keyframes c-breathe-edge {
  0%, 100% { border-color: var(--c-note-line) }
  50% { border-color: #C3BDD0 }
}
.c-droptar:hover, .c-droptar:focus-visible {
  border-color: var(--c-beam);
  background: linear-gradient(160deg, rgba(11, 117, 111, .07), var(--c-card) 55%);
}
.c-droptar .ttl {
  display: block;
  font-family: var(--c-sans);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.016em;
  color: var(--c-ink);
  margin: 14px auto 10px;
  max-width: 44ch;
  line-height: 1.35;
}
.c-droptar .ln {
  display: block;
  font-size: 13px;
  line-height: 1.6;
  color: var(--c-ink-2);
  margin: 0 auto;
  max-width: 62ch;
}
.c-droptar .qt {
  display: block;
  font-size: 12px;
  color: var(--c-meta);
  margin: 12px auto 0;
  max-width: 58ch;
}
.c-droptar .c-ico { width: 26px; height: 26px; margin: 0 auto; color: var(--c-beam) }
.c-dropalts { display: flex; gap: 8px; justify-content: center; margin-top: 18px; flex-wrap: wrap }

/* ==========================================================================
   12d. RESPONSIVE — the mock's own 900px block
   ==========================================================================
   A phone gets the columns that answer the question, not a sideways scroll
   through all of them. Secondary columns carry `.c-hide-sm` per page, which is
   a cargo decision: which column is secondary depends on what the list is
   about.
   ========================================================================== */
@media (max-width: 900px) {
  .c-hide-sm { display: none !important }
  .c-pagehead { margin-bottom: 38px }
  .c-section { margin-bottom: 38px }
  .c-section-head { gap: 8px }
  .c-section-head .c-rhs { margin-left: 0; width: 100% }
  .c-figs { gap: 26px }
  .c-rack { border-radius: var(--c-r) }
  .c-rack-tools { padding: 9px 10px }
  .c-rack-find { flex: 1 1 100% }
  .c-rack-count { margin-left: 0 }
  .c-rack-cell { padding: 12px 10px }
  .c-rack-sub { font-size: 11.5px }
  .c-rack-th.sel, .c-rack-cell.sel { padding-left: 10px; width: 34px }
  .c-rack-sort { padding: 11px 10px }
  /* The mock's detail cell is indented 55px to clear the tick column. On a
     phone the tick column is 34px and the indent would eat the editor, so the
     mock's own phone padding applies. */
  .c-rack-detail > td { padding-left: 16px }
  .c-droptar { padding: 30px 18px }
  .c-droptar .ttl { font-size: 15.5px }
}

/* ==========================================================================
   12e. THE PHONE STACK — below 640px a rack stops being a table
   ==========================================================================

   WHAT WAS MEASURED. `/app/b/…/rules` at 390×844 in Chrome, tour dismissed.
   Six rule rows: 321, 158, 272, 339, 308, 188 px. Two to three rules on screen
   for a brand with fifteen.

   THE MOCK'S OWN PHONE TREATMENT IS ALREADY IN FORCE ABOVE AND IS NOT ENOUGH.
   §12d drops secondary columns at 900px and Rules marks `Kind` and `Caught`
   with `.c-hide-sm`, so what a phone already gets is the reduced set. What it
   reduces TO is `Rule | Severity | Open`: the subject squeezed to 143px while a
   severity pill and a chevron hold the rest. The two columns the treatment
   cannot drop are the two the screen exists for, so there is nothing left to
   drop and the row is still three columns wide.

   A phone does not have a column problem, it has a MEASURE problem. Below 640
   the row stops being laid out sideways: the subject takes the full width and
   its facts become a line underneath.

   WHY 640, MEASURED RATHER THAN PICKED. Sweeping the rules rack by viewport
   width and reading the subject cell and the median row height:

       360–414 → 143px subject, 308px median row   (flat: the columns have hit
       480     → 199px          237px               min-content, so the subject
       540     → 259px          180px               cannot grow at all however
       600     → 319px          145px               wide the phone is)
       640     → 359px          136px
       700     → 419px          123px
       768     → 487px          123px

   640 is the first width where the subject holds ~48 characters and the median
   row is inside 140px. Below 480 the grid stops being fluid entirely. It also
   nests under §12d's 900 rather than fighting it: 900 drops the secondary
   columns, 640 stacks what is left.

   `:has()` DECIDES, SO THE OPT-OUT IS DECLARATIVE. Only a grid that named a
   subject stacks. A matrix — the control map, the register — marks no subject
   in its markup, so it does not match here and keeps the sideways scroll
   inside its own container, which is what `.wide` is for: a cell per axis per
   axis, where stacking would not shorten the question but delete it. If
   `:has()` were ever unavailable the rule simply would not apply and the rack
   would draw as it does today, which is the right way for this to fail.
   ========================================================================== */
@media (max-width: 640px) {
  .c-rack-grid:has([data-subject]) { display: block }
  .c-rack-grid:has([data-subject]) thead,
  .c-rack-grid:has([data-subject]) tbody { display: block }

  /*
    THE HEADER ROW BECOMES A SORT STRIP RATHER THAN DISAPPEARING.

    Hiding the head is the usual way to stack a table and it takes the sort
    controls with it — on this screen "order these by severity" is most of what
    a phone is for. So the heads that carry a control stay, laid out as a line
    of chips, and only the inert ones go: a static label and the actions column
    hold nothing to press, and in a stack each value is named beside itself.
  */
  .c-rack-grid:has([data-subject]) thead tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px;
    padding: 2px 4px;
    border-bottom: 1px solid var(--c-hairline);
  }
  .c-rack-grid:has([data-subject]) .c-rack-th {
    display: block;
    position: static;
    border-bottom: 0;
    width: auto;
  }
  .c-rack-grid:has([data-subject]) .c-rack-th.static,
  .c-rack-grid:has([data-subject]) .c-rack-th.act { display: none }
  .c-rack-grid:has([data-subject]) .c-rack-sort { padding: 8px 8px }

  /*
    THE ROW IS A WRAPPING LINE, NOT A FIXED STACK.

    The subject's flex-basis is its content, so a long rule cannot share a line
    and everything else wraps beneath it — while a SHORT subject (a person's
    name) still fits on one line with its facts, and that row does not get
    taller than it was. One rule, both behaviours, decided by the content.
  */
  .c-rack-grid:has([data-subject]) tr.c-rack-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px 10px;
    padding: 12px;
    position: relative;
  }
  /* The tick's lane is charged only to a rack that HAS a tick. House rules
     passes `bulk={null}` and was paying 34px of a 320px measure for a control
     capability had already removed. §12d's own 34px where it is earned. */
  .c-rack-grid:has([data-subject]) tr.c-rack-row:has(> .c-rack-cell.sel) {
    padding-left: 34px;
  }
  .c-rack-grid:has([data-subject]) .c-rack-cell {
    display: block;
    padding: 0;
    width: auto;
    white-space: normal;
    text-align: left;
  }
  /*
    THE TICK LEAVES THE FLOW, and that is worth 35px on every row.

    In the wrapping line it is a flex item, and the subject's basis is its own
    content — so a long rule could never share the line and the tick got one to
    itself above the rule it selects. Lifted out and given a lane, it sits
    against the rule's first line where it belongs, and the subject starts the
    line rather than the second one.
  */
  .c-rack-grid:has([data-subject]) .c-rack-cell.sel {
    position: absolute;
    left: 12px;
    top: 13px;
    padding: 0;
    width: auto;
  }
  /*
    THE TICK IS 15px, WHICH IS NOT A TAP TARGET. Measured on the real screen at
    390: 15×15, against WCAG 2.2 SC 2.5.8's 24×24 floor. The drawn box stays
    15px — it is the right size for the eye and the mock's own — and only the
    hit region grows, to 34×31.

    Asymmetric on purpose. The tick sits in a 34px lane at left:12, so it can
    grow to the lane's edges and no further: a symmetric expansion would reach
    under the first characters of the rule, and a press meant to open the fold
    would toggle a checkbox instead.
  */
  .c-rack-grid:has([data-subject]) .c-rack-cell.sel .c-tick::before {
    content: '';
    position: absolute;
    inset: -8px -7px -8px -12px;
  }
  .c-rack-grid:has([data-subject]) .c-rack-cell[data-subject] {
    flex: 1 1 auto;
    /* or the flex item refuses to shrink below its longest word's line box and
       the row overflows the card instead of wrapping. */
    min-width: 0;
  }
  /* Shrinkable, and the label rides BESIDE its value. Content-sized, a cell
     holding a control takes its natural width the moment it leaves a table
     cell; and an inline label sits ABOVE any value that is a block, which
     costs a line on every row. */
  .c-rack-grid:has([data-subject]) .c-rack-cell[data-label] {
    flex: 0 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .c-rack-grid:has([data-subject]) .c-rack-cell[data-label] select { max-width: 100% }

  /*
    A FACT KEEPS ITS NAME. With no header row above the cell, the severity pill
    is a loose word under the rule with nothing attaching it to "severity" —
    which on a governance screen is the fact the row is there to carry. This is
    the column header, moved inline, so it wears the header's voice exactly:
    sans, 600, .035em, `--c-meta` (#767061 — 4.85:1 on --c-card, 4.98:1 on the
    dark card). Not mono: mono is the governance accent and a label is chrome.
  */
  .c-rack-grid:has([data-subject]) .c-rack-cell[data-label]::before {
    content: attr(data-label);
    font-family: var(--c-sans);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .035em;
    color: var(--c-meta);
    flex: none;
  }
  /* except where the control names itself: the chevron already carries "Open
     this rule" as its accessible name and its tooltip, so the word beside it
     would be the third copy. */
  .c-rack-grid:has([data-subject]) .c-rack-cell.act[data-label]::before { content: none }
  .c-rack-grid:has([data-subject]) .c-rack-cell.act {
    flex: 0 0 auto;
    margin-left: auto;
    position: relative;
  }

  /*
    THE PROVENANCE RAIL MOVES TO THE ROW.

    It is drawn on `> :first-child` because a `tr` background is painted under
    the cells and a collapsed border eats it — true while this is a table, and
    not true here, where the row is a block and the first child is a 15px tick.
    A rail the height of the checkbox says nothing. Same three textures, same
    ink, same 2px.
  */
  .c-rack-grid:has([data-subject]) .c-rack-row[class*='tex-'] {
    background-repeat: no-repeat;
    background-size: 2px 100%;
    background-position: left top;
  }
  .c-rack-grid:has([data-subject]) .c-rack-row[class*='tex-'] > :first-child {
    background-image: none;
  }
  .c-rack-grid:has([data-subject]) .c-rack-row.tex-solid {
    background-image: linear-gradient(rgba(33, 29, 21, .42), rgba(33, 29, 21, .42));
  }
  .c-rack-grid:has([data-subject]) .c-rack-row.tex-dash {
    background-image: repeating-linear-gradient(180deg,
      rgba(33, 29, 21, .42) 0 7px, transparent 7px 12px);
  }
  .c-rack-grid:has([data-subject]) .c-rack-row.tex-fine {
    background-image: repeating-linear-gradient(180deg,
      rgba(33, 29, 21, .42) 0 3px, transparent 3px 6px);
  }

  .c-rack-grid:has([data-subject]) tr.c-rack-detail,
  .c-rack-grid:has([data-subject]) tr.c-rack-detail > td { display: block }
  .c-rack-grid:has([data-subject]) tr.c-rack-detail[hidden] { display: none }

  /* ------------------------------------------------------------------------
     THE INSTRUMENT'S LIST STACKS ON THE SAME TERMS.

     `.c-list` is `DataTable`'s table — Work, the busiest list in the product —
     and at 390 it had the disease worse than the rack did: a 967px table in a
     390px viewport, so the piece title wrapped at two or three words a line
     ("Veltriva HCP / email — / formulary / listing / announcement") while the
     campaign column sat off the right edge behind a sideways scroll with no
     cue that it was there.

     The subject needs no inference here. `DataTable` already decided it: it
     wraps the FIRST column's cell in the row's link and no other, so column
     zero is the row's name by the component's own hand, and the stack marks
     the same cell.
     --------------------------------------------------------------------- */
  .c-list:has([data-subject]) { display: block }
  .c-list:has([data-subject]) thead,
  .c-list:has([data-subject]) tbody { display: block }
  .c-list:has([data-subject]) thead tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 8px;
    padding: 2px 4px;
  }
  .c-list:has([data-subject]) thead th { display: block; width: auto; padding: 6px 4px }
  .c-list:has([data-subject]) tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px 10px;
    padding: 12px;
    position: relative;
  }
  .c-list:has([data-subject]) tbody tr:has(> .c-pick) { padding-left: 34px }
  .c-list:has([data-subject]) tbody td {
    display: block;
    padding: 0;
    width: auto;
    border: 0;
    white-space: normal;
    text-align: left;
  }
  .c-list:has([data-subject]) tbody td[data-subject] { flex: 1 1 auto; min-width: 0 }
  /* the name's desktop clamp is a column measure; stacked there is no column */
  .c-list:has([data-subject]) .c-name span { max-width: none }
  .c-list:has([data-subject]) tbody td[data-label] {
    flex: 0 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .c-list:has([data-subject]) tbody td[data-label]::before {
    content: attr(data-label);
    font-family: var(--c-sans);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .035em;
    color: var(--c-meta);
    flex: none;
  }
  /*
    THE PICK COLUMN KEEPS ITS HOVER CONTRACT. `.c-list .c-pick input` is
    `opacity:0` until the row is hovered or the list is picking — which on a
    phone means never, because there is no hover. Stacked, it is always drawn.
  */
  /* Out of the flow, or the subject's content basis pushes it onto a line of
     its own above the piece it selects — 40px a row. Same as the rack. */
  .c-list:has([data-subject]) .c-pick {
    position: absolute;
    left: 11px;
    top: 14px;
    flex: none;
    width: auto;
    padding: 0;
  }
  .c-list:has([data-subject]) .c-pick input {
    opacity: 1;
    position: relative;
    margin: 0;
  }
  /* and the same 24x24 floor: the drawn box is the browser's own checkbox,
     the hit region fills the 34px lane and stops before the subject. */
  .c-list:has([data-subject]) .c-pick input::before {
    content: '';
    position: absolute;
    inset: -8px -7px -8px -11px;
  }
}

/* ==========================================================================
   13. THE SHELL — `platform-shell-desk.html`, lifted
   ==========================================================================

   Source: `docs/superpowers/mockups/platform-shell-desk.html`. §12 lifted that
   file's `.rack` and its page furniture; this is the rest of its chassis — the
   object all four platform mocks sit inside. Graphite plate on top, warm paper
   between, graphite readout at the foot, and NOTHING else may become a
   permanent surface (spec §5).

   THE METHOD, AND IT IS NOT A SUGGESTION (spec §4a). Every declaration below
   was copied out of that file's `<style>` block: same selectors, same nesting,
   same property order, same values. Where a number here differs from the mock,
   that is a defect in this file and not a decision.

   THE MECHANICAL CHANGES, and there are only three kinds:

   1. Class names are prefixed `c-`, as §1 and §12 already do, because
      `mock.css` owns `.tab`, `.switcher`, `.stack`, `.av`, `.strip`, `.rail`
      and `.menu` globally in `@layer components`.

   2. TWO MORE names could not take a bare prefix, because an earlier section
      had already spent them on a different object. §12 records four; these are
      the fifth and sixth:

          mock `.plate` (the platform NAV)  ->  `.c-topplate`
              §5's `.c-plate` is the STUDIOS' plate — one crumb and one verb,
              46px. The platform's is 50px and carries six tabs. Same
              material, different object, different metrics, so they are two
              classes. They are both sans now; when this was written the
              studio plate was uppercase mono and the two could not have
              shared a rule even if they had wanted to.

          mock `.frame` (a lane row's deck thumbnail)  ->  `.c-lframe`
              `--c-frame` is the graphite token, named in ~60 declarations. A
              `.c-frame` class would make that token ungreppable, and this file
              is audited by grep. Named with its siblings `.c-lrow` / `.c-lname`
              instead.

   3. Two selectors are SCOPED to `.c-app` that are unscoped in the mock —
      `.c-canvas` and `.c-seltool.floating`. Both already exist and are already
      in use on surfaces that are NOT inside this shell (Rules, the Carousel
      studio), and the mock's values for them are correct only for a child of
      `.c-body`. The scope is what stops a shell rule reaching a surface that
      has no shell.

   NOTHING IS ADAPTED, ROUNDED OR IMPROVED. The two AA corrections that §1 and
   §7 already carry — `--c-meta` and the menu's aside grey — are inherited, not
   restated at the mock's failing values. One more of the same kind is made
   below, on `.c-strip .x`, and it is computed rather than judged.
   ========================================================================== */

/*
 * `position: relative` so the bulk bar and anything else that floats is
 * positioned against the app rather than the viewport. In the mock the app is a
 * framed instrument on a page; in production it fills the viewport and the two
 * are the same box. This is what keeps them honest.
 */
.c-app {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--c-paper);
  overflow: hidden;
  position: relative;
}

/* ---- the top plate: the nav -------------------------------------------
   Tabs are SANS: they are chrome, not readout. Today's platform sets nav links
   in mono, which is named defect 4 in the spec. */
.c-topplate {
  background: var(--c-frame);
  color: var(--c-readout);
  flex: none;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 12px 0 16px;
  height: 50px;
  font-family: var(--c-sans);
  position: relative;
  z-index: 40;
}

.c-topplate .left { display: flex; align-items: center; gap: 16px; min-width: 0; flex: 1 }
.c-topplate .rhs { margin-left: auto; display: flex; align-items: center; gap: 10px; flex: none }

.c-tabs {
  display: flex;
  align-items: center;
  gap: 1px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.c-tabs::-webkit-scrollbar { display: none }

/* `flex: none` or the tabs crush into each other the moment they overflow. */
.c-tab {
  font-family: var(--c-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--c-readout);
  text-decoration: none;
  padding: 7px 11px;
  border-radius: var(--c-r-sm);
  flex: none;
  white-space: nowrap;
  position: relative;
  background: none;
  border: 0;
  cursor: pointer;
}
.c-tab:hover { background: var(--c-frame-2); color: var(--c-readout-hi) }
.c-tab.on { color: var(--c-readout-hi); background: var(--c-frame-2) }
.c-tab.on::after {
  content: "";
  position: absolute;
  left: 11px;
  right: 11px;
  bottom: 2px;
  height: 1.5px;
  background: var(--c-beam-frame);
  border-radius: 1px;
}
/* A door painted on a wall: reachable, no longer claiming to be live. */
.c-tab.off { opacity: .38 }

.c-switcher {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid var(--c-frame-line);
  border-radius: var(--c-r-sm);
  color: var(--c-readout-hi);
  font-family: var(--c-sans);
  font-size: 12.5px;
  padding: 6px 10px;
  cursor: pointer;
  max-width: 280px;
  white-space: nowrap;
}
.c-switcher:hover { background: var(--c-frame-2) }
.c-switcher > span { overflow: hidden; text-overflow: ellipsis }
.c-switcher .dim { color: var(--c-readout-dim) }

.c-topplate .live { display: flex; align-items: center; gap: 6px; color: var(--c-beam-frame) }
.c-topplate .live i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--c-beam-frame);
  display: block;
  flex: none;
  animation: c-breathe 1.6s ease-in-out infinite;
}

/*
 * THE JOB TRAY, ON THE PLATE.
 *
 * The mock draws work-that-outlives-the-screen as a `.switcher` with a
 * breathing beam dot and a mono readout — "Reading · 3 of 11". The product
 * already has that object: `jobWidget.tsx`, built for the white bar this shell
 * replaces, and it knows things the mock's pill does not (what failed, how long
 * it has been running, how to stop it). So the widget keeps its markup and gets
 * the mock's skin here, scoped to the plate.
 *
 * The PANEL is deliberately left alone. It is a menu on paper, which is what
 * `.c-menu` is too, and giving it a graphite ground would make the one surface
 * in this shell that lists failures the hardest one to read.
 */
.c-topplate .jobw { position: relative; flex: none }
.c-topplate .jobwbtn {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid var(--c-frame-line);
  border-radius: var(--c-r-sm);
  color: var(--c-readout-hi);
  font-family: var(--c-sans);
  font-size: 12.5px;
  padding: 6px 10px;
  cursor: pointer;
  max-width: 280px;
  white-space: nowrap;
}
.c-topplate .jobwbtn:hover { background: var(--c-frame-2) }
.c-topplate .jobwbtn .jobwn { min-width: 0; display: flex; align-items: baseline; gap: 6px }
.c-topplate .jobwbtn .jobwn b { color: var(--c-readout-hi); font-weight: 600 }
.c-topplate .jobwbtn .jobwn span { color: var(--c-readout-dim); overflow: hidden; text-overflow: ellipsis }
.c-topplate .jobwbtn .jobwt { color: var(--c-beam-frame) }
.c-topplate .jobdot, .c-topplate .jobspin {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--c-beam-frame);
  border: 0;
  display: block;
  flex: none;
  animation: c-breathe 1.6s ease-in-out infinite;
}
.c-topplate .jobdot.bad { background: var(--c-flag); animation: none }

.c-stack { display: flex; align-items: center }
.c-stack .c-av { margin-left: -7px; box-shadow: 0 0 0 2px var(--c-frame) }

.c-av {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  font-family: var(--c-sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
  flex: none;
  position: relative;
  text-decoration: none;
}
.c-av.sm { width: 22px; height: 22px; font-size: 9px }
.c-av .on2 {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-beam-frame);
  box-shadow: 0 0 0 2px var(--c-frame);
}
/*
 * NOT IN THE MOCK, because the mock has no real people in it.
 *
 * The provider picture covers the initials rather than replacing them, so a
 * slow or dead avatar URL degrades to the letters that were always there
 * instead of to an empty circle. Carried across from `mock.css`'s `.avimg`,
 * whose call site in `Shell.tsx` explains the same reasoning.
 */
.c-av img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* ---- the account banner strip: ambient, one notice, never two ---------- */
.c-strip {
  flex: none;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 18px;
  background: var(--c-note-bg);
  border-bottom: 1px solid var(--c-note-line);
  font-size: 13px;
  color: #4A4655;
  z-index: 20;
}
.c-strip.warn { background: var(--c-flag-wash); border-bottom-color: #F0D3E1 }
.c-strip i.d {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-beam);
  display: block;
  flex: none;
}
.c-strip.warn i.d { background: var(--c-flag) }
.c-strip b { color: #211D28; font-weight: 600; flex: none }
.c-strip .txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.c-strip .c-btn { margin-left: auto; flex: none }
/*
 * `#716B7F`, NOT the mock's `#847E92`, and it must not be "restored".
 *
 * Measured on this strip's own grounds, the mock's grey is 3.51:1 on
 * `--c-note-bg` (#F4F2F6) and 3.46:1 on the warn strip's `--c-flag-wash`
 * (#FBEEF4) — both short of AA for the glyph it draws, which is not large
 * text. This is the same correction §7 already applies to the menu's aside,
 * and it is the same hue: #716B7F is 4.59:1 and 4.53:1 on those two grounds.
 * Computed, not judged — an earlier pass on this codebase tried to fix a
 * failing grey by LIGHTENING it and made it worse.
 */
.c-strip .x {
  background: none;
  border: 0;
  color: #716B7F;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 4px 5px;
  border-radius: 4px;
  flex: none;
  display: grid;
  place-items: center;
}
.c-strip .x:hover { background: rgba(33, 29, 21, .06) }

/* ---- body: rail + canvas ----------------------------------------------- */
.c-body { flex: 1; display: flex; min-height: 0 }
/*
 * Anything in the body that is NOT the rail takes the rest of the row.
 *
 * The mock's body has exactly two children and names them both. The app's body
 * has one `<Outlet>`: a converted screen renders the rail and the canvas as
 * siblings, an unconverted one renders a single `.railshell` grid. Both want
 * the same thing — fill the row, and be allowed to shrink.
 */
.c-body > *:not(.c-rail) { flex: 1; min-width: 0; min-height: 0; overflow-y: auto }

/*
 * WHAT AN UNCONVERTED SCREEN NEEDS FROM THE SHELL, AND ONLY THAT.
 *
 * `.railshell` is `mock.css`'s rail grid, on the eight screens no wave has
 * reached. Two things change for it under this shell and both are consequences
 * of the shell rather than opinions about those screens:
 *
 *   IT IS THE SCROLLER NOW. The old shell was a page that scrolled with the
 *   window; this one is a fixed instrument whose canvas scrolls inside it. The
 *   rule above gives every body child that scroller, so a long list on an
 *   unconverted screen is still reachable.
 *
 *   ITS RAIL STICKS AT THE TOP, not 78px down. That offset cleared a masthead
 *   that used to scroll away with the page. The plate is outside the scroller
 *   now, so 78px is a gap under nothing.
 */
.c-app .railshell > .rail { top: 0 }

.c-rail {
  flex: none;
  width: 214px;
  border-right: 1px solid var(--c-hairline);
  padding: 20px 10px;
  overflow-y: auto;
}
.c-rail-lab { color: var(--c-meta); padding: 0 10px 9px }
.c-railitem {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: var(--c-r-sm);
  padding: 9px 10px;
  font-family: var(--c-sans);
  font-size: 13.5px;
  color: var(--c-ink-2);
  cursor: pointer;
  text-decoration: none;
}
.c-railitem:hover { background: rgba(33, 29, 21, .045); color: var(--c-ink) }
.c-railitem.on { background: rgba(33, 29, 21, .065); color: var(--c-ink); font-weight: 600 }
/* In the design and not in the product: dimmed and unlinked, never removed.
   The rail's own `off` state, kept from the component it replaces. */
.c-railitem.off { opacity: .45; cursor: default }
.c-railitem .n { margin-left: auto; color: var(--c-meta) }
.c-railitem.on .n { color: var(--c-beam) }
.c-railitem .c-ico { color: var(--c-meta) }
.c-railitem.on .c-ico { color: var(--c-beam) }
.c-rail hr { border: 0; border-top: 1px solid var(--c-hairline); margin: 16px 10px }

/*
 * The canvas scrolls; the shell does not. Scoped to `.c-app` — see the header.
 * `.c-canvas` is already the ground under Rules and the Carousel studio, and
 * neither has a flex parent to be `flex: 1` inside nor a bounded height to
 * scroll against. Outside the shell these declarations are at best inert and
 * at worst a second scrollbar.
 */
.c-app .c-canvas { flex: 1; min-height: 0; overflow-y: auto; scroll-behavior: smooth }

/*
 * The mock docks its bulk bar 60px up — clear of the 44px readout plate with
 * the beat to spare. §8's `.c-seltool.floating` sits at 24px, which was right
 * while no surface had a plate beneath it and is behind one now. Scoped, so a
 * rack on a page with no shell keeps the geometry §8 measured for it.
 */
.c-app .c-seltool.floating { bottom: 60px }

/*
 * THE READOUT PLATE HOLDS ONE LINE, WHICH IS WHAT MAKES IT A PLATE.
 *
 * `platform-shell-desk.html` says so and the studio mock §5 was lifted from
 * does not, because a studio's sentence is short and a platform's names a
 * brand. Without these the plate grew to three lines at 390 and the aux facts
 * collided with the sentence — measured, not theorised. Scoped, so §5's plate
 * on the two studios keeps exactly the metrics it was drawn with.
 */
.c-app .c-status .c-sentence { min-width: 0 }
.c-app .c-status .c-sentence span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* ==========================================================================
   14. THE DESK'S CARGO — the same file, below its chassis line
   ==========================================================================
   Everything in §13 is byte-identical across the four platform mocks. These
   parts exist only because this screen is the Desk.
   ========================================================================== */

/* The sweep report: what the product did overnight. Small by construction —
   at most three findings, two lines on a quiet day. */
.c-away {
  border: 1px solid var(--c-hairline);
  border-radius: var(--c-r-card);
  background: linear-gradient(158deg, rgba(11, 117, 111, .055), var(--c-card) 62%);
  padding: 21px 23px;
  margin: 0 0 var(--c-gap-section);
}
.c-away .hd { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap }
.c-away .hd .c-eyebrow { display: flex; align-items: center; gap: 8px; color: var(--c-ink-2) }
.c-away .hd .meta { margin-left: auto; color: var(--c-meta) }
.c-awaybar {
  display: flex;
  gap: 2px;
  height: 4px;
  border-radius: 3px;
  overflow: hidden;
  background: rgba(33, 29, 21, .075);
  margin: 15px 0 19px;
}
.c-awaybar i { display: block; height: 100% }
.c-awaylead {
  font-family: var(--c-sans);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -.024em;
  margin: 0 0 9px;
  line-height: 1.25;
}
.c-awaywhy { margin: 0; font-size: 13.5px; line-height: 1.62; color: var(--c-ink-2); max-width: 70ch }
.c-away .acts { margin-top: 16px }
.c-awayrest { margin: 20px 0 0; border-top: 1px solid var(--c-hairline) }

/*
 * THE DESK'S LANES STAY BESPOKE, and that is the spec's own carve-out (§3:
 * "bespoke lists remain only where a table is genuinely wrong — the Desk's
 * lanes"). A row here is a piece of work with a face: the deck's own frames,
 * its standing, and who is holding it. Forced into the rack it would lose the
 * thumbnail that makes it recognisable at a glance, which is the whole job of
 * this screen. It keeps the rack's rhythm — same row height, same hairline,
 * same hover — so the two read as siblings rather than as two products.
 */
/*
 * NO `overflow: hidden`, WHICH THE MOCK HAS. This is a correction, not a drift.
 *
 * The mock clips the lane so a hovered first row cannot square off the rounded
 * corner. It also puts a row menu inside every lane row — `#hand1`, "Hand it
 * to" — and `overflow: hidden` clips that menu to the lane whatever its
 * z-index is. Measured in Chrome on the fixture account: the last three of
 * seven seats were below the lane's edge and unreachable, on the control whose
 * whole job is choosing a person. The mock's own chassis comment names this
 * class of defect — "a control that looks like it works".
 *
 * So the corner is rounded where the corner is, on the first and last rows, and
 * nothing is clipped that somebody needed.
 */
.c-lane {
  border: 1px solid var(--c-hairline);
  border-radius: var(--c-r-card);
  background: var(--c-card);
}
.c-lrow:first-child { border-top-left-radius: var(--c-r-card); border-top-right-radius: var(--c-r-card) }
.c-lrow:last-child {
  border-bottom-left-radius: var(--c-r-card);
  border-bottom-right-radius: var(--c-r-card);
}
.c-lrow {
  display: grid;
  /* 55px, not 48px: the deck's thumbnail now shows the edges of the frames
     standing behind it (`.c-ldeck`) and the column reserves that room rather
     than letting them eat the gap. */
  grid-template-columns: 55px minmax(0, 1fr) 118px 150px auto;
  gap: 16px;
  align-items: center;
  padding: 13px 16px;
  border-bottom: 1px solid rgba(33, 29, 21, .07);
}
.c-lrow:last-child { border-bottom: 0 }
.c-lrow:hover { background: rgba(33, 29, 21, .028) }
.c-lrow.hot {
  box-shadow: inset 2px 0 0 var(--c-flag);
  background: linear-gradient(90deg, var(--c-flag-wash), transparent 58%);
}
.c-lrow.hot:hover {
  background: linear-gradient(90deg, var(--c-flag-wash), rgba(33, 29, 21, .028) 58%);
}
/*
 * The lane's deck thumbnail, and the edges of the frames behind it.
 *
 * The calm system draws this at 44x56 rather than the mock's 50x64, so it
 * keeps its own classes — but it is the same OBJECT as the work list's tile
 * and says the same two things about it: the brand's colour, and that there is
 * more than one frame. A deck of one frame draws no edge.
 */
.c-ldeck {
  position: relative;
  display: inline-flex;
  padding-right: 7px;
}
.c-ldeck .c-lstack {
  position: absolute;
  top: 3px;
  bottom: 3px;
  right: 0;
  width: 10px;
  border-radius: 0 4px 4px 0;
  opacity: .5;
  z-index: 1;
}
.c-ldeck .c-lstack:nth-of-type(2) { right: 3px; opacity: .3 }
.c-ldeck .c-lframe { position: relative; z-index: 2 }
.c-lframe {
  width: 44px;
  height: 56px;
  border-radius: 5px;
  padding: 5px 4px;
  overflow: hidden;
  position: relative;
  color: #fff;
  font-family: var(--c-serif);
  font-size: 6.5px;
  line-height: 1.35;
}
.c-lframe .b {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--c-flag);
  color: #fff;
  font-family: var(--c-sans);
  font-size: 7px;
  font-weight: 700;
  display: grid;
  place-items: center;
}
.c-lname { font-size: 13.5px; font-weight: 600; color: var(--c-ink); display: block; text-decoration: none }
a.c-lname:hover { text-decoration: underline; text-underline-offset: 3px }
.c-lsub { display: flex; align-items: center; gap: 6px; margin-top: 5px; color: var(--c-meta) }
.c-lwho { display: flex; align-items: center; gap: 9px; min-width: 0; font-size: 12.5px; color: var(--c-ink-2) }
.c-lwho .col { min-width: 0 }
.c-lwho .col b { font-weight: 500; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.c-lwho .col .when { display: block; margin-top: 3px; color: var(--c-meta) }
.c-lacts { display: flex; align-items: center; gap: 6px; justify-content: flex-end; position: relative }

/* The load bar in a brand row — three segments, one per standing. */
.c-bar {
  display: flex;
  height: 7px;
  border-radius: 4px;
  overflow: hidden;
  background: rgba(33, 29, 21, .08);
  min-width: 120px;
}
.c-bar i { display: block; height: 100% }

/* A control-map cell: a state, then whatever qualifies it. */
.c-cm {
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: flex-start;
  text-decoration: none;
  color: inherit;
}
/*
 * `background`, `border`, `padding` AND `margin`, on a rule that needs none of
 * them.
 *
 * `mock.css` owns a bare `.q` — a bordered card on `--surface` — and this
 * qualifier is a `.q` inside `.c-cm`. Layer order only decides declarations
 * that EXIST here, so with `color` alone the control map drew every coverage
 * qualifier inside a white bordered box. Caught in Chrome, not by a test.
 */
.c-cm .q {
  color: var(--c-meta);
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  margin: 0;
}
.c-cardgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 12px }

/* ==========================================================================
   14b. RESPONSIVE — the shell's and the Desk's own 900px blocks
   ========================================================================== */
@media (max-width: 900px) {
  .c-topplate { gap: 10px; padding: 0 8px 0 12px; height: 48px }
  .c-topplate .left { gap: 10px }
  .c-topplate .rhs { gap: 6px }
  .c-switcher { max-width: 132px; padding: 6px 8px }
  .c-body { flex-direction: column }
  /* The rail becomes a scrolling chip row: same items, same counts, one line. */
  .c-rail {
    width: auto;
    flex: none;
    border-right: 0;
    border-bottom: 1px solid var(--c-hairline);
    padding: 9px 10px;
    display: flex;
    gap: 5px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .c-rail::-webkit-scrollbar { display: none }
  .c-rail-lab, .c-rail hr { display: none }
  .c-railitem {
    width: auto;
    flex: none;
    border: 1px solid var(--c-hairline);
    border-radius: var(--c-r-pill);
    padding: 6px 12px;
    font-size: 12.5px;
    gap: 7px;
  }
  .c-railitem.on { background: var(--c-frame); border-color: var(--c-frame); color: var(--c-readout-hi) }
  .c-railitem.on .n, .c-railitem.on .c-ico { color: var(--c-beam-frame) }
  .c-app .c-seltool.floating { bottom: 52px }
  .c-app .c-status { gap: 10px; padding: 9px 12px; font-size: 11px; min-height: 40px }
  /* The sentence is the readout. The aux facts are what it is made of, and on
     a phone there is room for one of the two. */
  .c-app .c-status .c-aux { display: none }
  .c-lrow { grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; padding: 12px }
  .c-lrow .c-lwho { grid-column: 2 / 4; font-size: 12px }
  .c-lrow .lstand { grid-column: 2 / 4 }
  .c-lacts { grid-column: 1 / 4; justify-content: flex-start; margin-top: 2px }
  .c-away { padding: 17px 16px }
  .c-awaylead { font-size: 18px }
}

/* A confirmation that offers the middle path.
   Deleting a rule orphans every record pointing at its id; standing it down
   keeps the history and stops it firing, and is almost always what was
   actually wanted. */
.c-confirm { display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
.c-confirm-q { font-size: 13px; color: var(--c-ink-2, #4a4655); margin-right: 4px }

/* The count of rules that catch nothing. Emphasised by weight like every other
   figure on that row, rather than by the colour that means a stopped release. */
.c-fig .n.gap { color: var(--c-ink, #211d15); font-weight: 600 }
/* ==========================================================================
   CAROUSEL STUDIO · DIRECTION B1 — "THE BENCH"
   ==========================================================================
   LIFTED FROM `docs/superpowers/mockups/carousel-b1-bench.html`.

   This file is the mock's <style> block, verbatim: same selectors, same
   property values, same order. It is not "inspired by" the mock and it is not
   a restyle of the old editor's CSS — the old editor had no CSS of its own,
   it had Tailwind utilities on a different DOM, and that DOM is deleted.

   What was DROPPED from the lift, and why:

     .rationale / .demo-strip / .lifts / .demo-btn / .demo-hint / kbd
        The mock's own explanatory band. `calm-system-rollout.md` §4a names
        this "a clearly-marked demo strip" and says a mock is production
        material *beyond* it. It is not product chrome.

     .slide / .el[data-el=…] / .body-col / .postcard-artwork
        The mock paints one fixture brand kit ("Veltriva · Clinic") explicitly,
        and says why in its own comment: "a brand kit is content, not chrome."
        The product's artwork comes from `src/slide/slide.css` + `SlideView`,
        which is ALSO what the exporter renders — two renderers for one frame
        is the one thing this codebase must never have. Everything the mock
        draws AROUND the artwork (the shadow, the edge, the ring, the handles,
        the guides, the freeze rule, the contenteditable rule, the squiggle) is
        chrome and is lifted below.

     .seltool's chassis properties
        `src/design/calm.css` already carries Direction B's selection capsule
        as `.c-seltool`, and §4b of the rollout is explicit: one chassis
        everywhere, studio-specific cargo. The mock's `.seltool` block and
        `.c-seltool` are the same measurements (graphite ground, 9px radius,
        4px padding, 2px gap, 29px buttons, 1×16px dividers, the same two-layer
        shadow) — so redrawing them here would be the second bar the owner
        forbade. The capsule element wears BOTH classes; `.seltool` below keeps
        only what is B1's: where it is placed, which way its menu opens, and
        its cargo (the pink finding verb, the type-size stepper).

   Everything else is the mock. If the mock says `padding: 18px 22px 16px`,
   this file says `padding: 18px 22px 16px`.
   ========================================================================== */

.bench-page {
  /* ---- the artwork's own, literal, because artwork is content -----------
     NOT NAMED `--paper`, WHICH IS `mock.css`'S AND IS THE PAGE'S. Declared
     under that name here it shadowed the token on the very element the whole
     theme hangs off — the studio root paints itself from that token, so it
     resolved to the artwork's cream in both themes, and every board rule that
     puts a label on the page's paper took the cream with it. Measured on the
     running screen, which is the only way this class of bug is ever found. */
  --art-paper: #FBF8F2;
  --p-ink: #211D15;
  --p-ink-2: #6B6455;
  /* B's #9A927F lands at 2.9:1 on paper, and B1 sets it at 8–9px. Same role,
     same hue, darkened to clear AA. */
  --p-meta: #6E6656;
  --p-hairline: rgba(33, 29, 21, .14);

  /* ---- the instrument: graphite in both themes, over artwork ------------ */
  --frame: #2B2833;
  --frame-2: #37333F;
  --frame-line: #443F4E;
  --readout: #BEB8CA;
  --readout-dim: #847D93;
  --readout-hi: #F4F2F8;
  /* --readout-dim carries text at 8.5–12px on the frame, where it lands at
     3.3:1. This is the same role at AA. */
  --readout-lo: #9C95AD;
  --spine-face: #2B2833;
  --spine-line: #443F4E;
  /* The beam, kept bright, because the surfaces that use this one are the
     graphite ones. `mock.css`'s `--beam` is the page's and is used wherever
     the ground is page. */
  --beam-frame: #22E0D5;
  /*
   * THE SIGNAL FAMILY ON GRAPHITE, for the same reason as `--beam-frame` and
   * measured rather than assumed.
   *
   * `mock.css` picks `--flag` and `--judge` against the PAGE's ground and
   * flips them with the page. The instrument does not flip, so a page token
   * on it is chosen against a ground it never meets: `--judge` in the light
   * theme is `#6D5B8F`, and on `#2B2833` that is **2.44:1** — under the 3:1
   * floor a mark has to clear, on the capsule verb that says a finding needs
   * a person. Measured with `shots/P6-a/scripts/capsule.mjs`.
   *
   * These are the values `mock.css` itself chose for a dark ground, held
   * fixed: `#FF2E8E` is 4.15:1 and `#B49BE8` is 6.05:1 on `#2B2833`, in both
   * themes, because neither moves. Same argument as `pitch.css`'s
   * `--flag-bright` on the one frame that is not paper.
   */
  --flag-frame: #FF2E8E;
  --judge-frame: #B49BE8;
  /* Alignment guides ride over arbitrary brand artwork, so the beam gets a
     light halo rather than a second colour (see .guide). */
  --guide: #0B756F;

  /* ---- the room: mock.css's, so it flips ------------------------------- */
  --bench: var(--surface-3);
  --bench-lift: rgba(255, 255, 255, .30); /* the lamp over the bench */
  --bench-ink: var(--ink);
  --bench-ink-2: var(--ink-2);
  --bench-line: var(--line-strong);
  --note-bg: var(--surface);
  --note-line: var(--line);
  --note-meta: var(--ink-3);
  /*
   * THE ADVISORY MARK IS NOT A SOFT PINK ANY MORE, AND `--flag-soft` IS GONE.
   *
   * It was `#E489B6` — the signature magenta with the volume down — and it
   * painted the strip's advisory pip and the capsule's advisory verb. The
   * colour law does not have a quiet magenta: a finding either stops a release
   * or it does not, and one that does not is a thing for a person to look at.
   * That is `--judge`, which is also what the board's own advisory card wears
   * (`.fnd2.judge`, `pitch.css`).
   *
   * The alias `--flag-soft: var(--judge)` survived one round to feed
   * `toolrail.css`, which paints the spine's news dot. That put a PAGE token on
   * the rail's graphite gradient — 2.4:1 in the light theme — so the rail now
   * asks for `--judge-frame` and the alias is deleted. A token called
   * `--flag-soft` holding a colour that is not the flag was a trap for whoever
   * greps the signature next.
   */

  /* ---- the shared capsule's own tokens, stated rather than inherited ----
     `.c-seltool` is `calm.css`'s chassis and the capsule wears it; every value
     in it is a `--c-*` custom property that `calm.css` declares on `.calm`.
     The studio root used to carry that class, and it also carried
     `color: var(--c-ink)` — a light-theme literal on the element every mock
     token has just been flipped for. Dropping the class fixed the theme and
     emptied the capsule: `background: var(--c-frame)` resolved to nothing and
     the bar rendered as loose glyphs floating on the artwork, seen on screen.

     So the chassis gets its palette from the instrument above rather than
     from a stylesheet the Bench no longer wears. Graphite in both themes, for
     the reason the block above gives. */
  --c-frame: var(--frame);
  --c-frame-2: var(--frame-2);
  --c-frame-line: var(--frame-line);
  --c-readout-hi: var(--readout-hi);
  --c-note-line: var(--note-line);
  --c-beam: var(--beam-frame);
  --c-serif: var(--serif);
  --c-mono: var(--mono);
  --c-sans: var(--sans);
  --c-gov-md: 10.5px;
  --c-gov-track: .13em;
  --c-gap-tight: 4px;
  --c-gap-xs: 6px;
  --c-gap-sm: 8px;
  --c-gap-md: 11px;
  --c-r-sm: 6px;
  --c-r: 9px;
  --c-r-pill: 999px;
  --c-e-seltool: 0 3px 8px rgba(23, 21, 28, .2), 0 12px 34px rgba(23, 21, 28, .3);
  --c-e-capsule: 0 1px 2px rgba(23, 21, 28, .06);
  --c-beat-3q: .18s;

  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.bench-page *,
.bench-page *::before,
.bench-page *::after { box-sizing: border-box; min-width: 0 }
.bench-page svg { display: block }
.bench-page button { font: inherit }

.bench-page .ico {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
.bench-page .ico.s { width: 13px; height: 13px }
.bench-page .sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.bench-skip {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 120;
  transform: translateY(-160%);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  padding: 10px 14px;
}
.bench-skip:focus { transform: none }

/* The beam is the focus ring on any lit surface; the frame's brighter beam
   only where the ground is graphite. Exactly B's two-tone rule. */
.bench-page :focus-visible { outline: 2px solid var(--beam); outline-offset: 2px }
.plate :focus-visible, .status :focus-visible, .strip :focus-visible,
/* `.spine` was the focusable thing itself when it was one button. It is the
   rail now and the focusable things are inside it, so this is a descendant
   selector or it silently stops covering anything. */
.spine :focus-visible, .seltool :focus-visible,
.release-cargo :focus-visible, .doorscrim .doorcard :focus-visible,
.bench[data-lights="dim"] .stage :focus-visible,
.bench[data-lights="out"] .stage :focus-visible { outline-color: var(--beam-frame) }
.doorcard :focus-visible { outline-color: var(--beam) }
/*
 * ONE RECTANGLE AROUND A SELECTED ELEMENT, NOT TWO.
 *
 * Every `[data-el]` is a tab stop, so a selected element drew the ring on its
 * box AND the rule above 3px outside it — two teal rectangles in the same
 * colour, measured on the real screen at both 1440 and 1728. The `.ring` IS
 * this element's focus indicator: it is drawn from the same box, it is the
 * thing that carries the resize handles, and it is more visible than an outline
 * because it is haloed to survive arbitrary brand artwork.
 *
 * Safe only because `releaseCanvasFocus` holds the other half of the invariant
 * — focus on a canvas element means that element is the selected one, so the
 * ring is always there when this rule takes the outline away. Ablate that and
 * `canvasFocusLadder.test.tsx` goes red.
 */
.bench-page .slide [data-el]:focus-visible { outline: none }
.bench-page ::selection { background: rgba(11, 117, 111, .16) }
/* Selected words on a frame keep the frame's own ink. The app-level selection
   foreground follows the CHROME theme, and a dark-theme near-white foreground
   over a light frame erased the selected word. The frame carries its own
   ground, so its selection inherits its own colour and deepens the wash
   enough to stay visible on cream. */
.bench-page .slide ::selection { background: rgba(11, 117, 111, .3); color: inherit }

/* ---------- tooltips: every icon explains itself on rollover ------------- */
.bench-page [data-tip] { position: relative }
.bench-page [data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--frame);
  color: #E7E4EE;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.3;
  padding: 5px 9px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease-out .3s;
  z-index: 60;
}
.bench-page [data-tip]:hover::after,
.bench-page [data-tip]:focus-visible::after { opacity: 1 }
.bench-page [data-tip].tip-below::after { bottom: auto; top: calc(100% + 9px) }
/*
 * TO THE SIDE, for a control that is taller than it is wide.
 *
 * The spine is a 19px icon rail running the full height of the frame. A tip
 * above it would open somewhere near the ceiling, hundreds of pixels from the
 * pointer that asked for it, and would land over the artwork on the way.
 */
.bench-page [data-tip].tip-right::after {
  bottom: auto;
  left: calc(100% + 9px);
  top: 50%;
  transform: translateY(-50%);
}
/*
 * A TOOLTIP THAT HAS BEEN ANSWERED SHUTS UP.
 *
 * `⋯` keeps the pointer on itself while its menu is open, so its tip stayed up
 * over the menu it had just opened — the label and the thing the label
 * describes, on screen at once, one covering the other. Anything that says what
 * it did by opening no longer needs to say what it does.
 */
.bench-page [data-tip].tip-left::after { left: auto; right: 0; transform: none }
/*
 * KNOWN, AND DELIBERATELY LEFT ALONE. `.tip-right` is declared TWICE — once at
 * the top of this section to push the tip BESIDE the control, and again on the
 * next line with `left: 0`, which is the `calm.css` rule and means something
 * else entirely (anchor the tip at the element's own left edge, for a tip that
 * would otherwise clip off the right of the window). Same specificity, so the
 * second one wins and the first is dead.
 *
 * That is why the DECK spine's tooltip — added precisely so an icon rail would
 * explain itself — rendered ON TOP of the artwork it sits beside: measured at
 * `left: 0px; transform: none` on the running browser, 270px of label across
 * the frame's own headline.
 *
 * The rail no longer rides this class. `toolrail.css` states its own placement
 * rather than depending on which stylesheet loaded last, so the rail is fixed
 * whichever of these two rules is live. The duplicate stays because
 * `Bench.tsx`'s back button asks for `tip-below tip-right` together and has
 * been drawn against the behaviour below since it was written; deleting this
 * line moves that control's tooltip, which is a different slice's business.
 */
.bench-page [data-tip].tip-right::after { left: 0; transform: none }

/* ========================= THE BENCH ==================================== */
/* The mock's `.bench` is a card on a page with a max-width and a bottom
   margin, because a mock is a specimen on a sheet. In the product the bench IS
   the route, so it fills the viewport the router gives it. Every other
   measurement — radius, the two-layer shadow, the flex column, the ground — is
   the mock's. */
.bench {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  overflow: hidden;
  position: relative;
  background: var(--bench);
}

/* Interaction geometry is larger than the glyph. Compact chrome remains
   visually compact while every pointer and touch target clears 44×44. */
.bench :is(.backbtn, .chip, .lens button, .iconbtn, .release, .signoff, .beat, .stripadd, .findingrow button) {
  min-width: 44px;
  min-height: 44px;
}

/* ---------- top plate: identity, the check, one verb, one menu ---------- */
.plate {
  background: var(--frame);
  color: var(--readout);
  flex: none;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 14px 0 18px;
  height: 46px;
  /* The plate names the brand and the deck. A brand name and a deck title are
     words somebody chose, so they are set in the UI sans at a readable size —
     not in the tracked uppercase mono the mock used, which pushed a person's
     own title through a typewriter. `text-transform` inherits into the
     `.decktitle` input, so the uppercase had to go from here for the title to
     come back as it was typed. */
  font-family: var(--sans);
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
  position: relative;
  z-index: 40;
}
.plate:has(.menu.open) { z-index: 68; }
/* The crumb is the shrinkable half of the plate. Without min-width: 0 the
   right-hand controls overlap it at 1024 and under an open dock instead of
   the name truncating. */
.plate .crumb { display: flex; align-items: center; gap: 9px; white-space: nowrap; overflow: hidden; flex: 1 1 auto; min-width: 0 }
.backbtn {
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  color: var(--readout);
  width: 26px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  flex: none;
}
.backbtn:hover { background: var(--frame-2); color: var(--readout-hi) }
.plate .crumb b { color: var(--readout-hi); font-weight: 600 }
.plate .crumb span { overflow: hidden; text-overflow: ellipsis }
.unsaved { color: var(--readout-lo); visibility: hidden }
.unsaved.on { visibility: visible }
.plate .rhs { margin-left: auto; display: flex; align-items: center; gap: 9px; position: relative; flex: none; white-space: nowrap }
.bench > .plate .chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--frame-line);
  border-radius: 999px;
  padding: 4px 11px;
  color: var(--readout);
  background: none;
  cursor: pointer;
  /* Sans: the chip says "1 blocking" or "No frames to check" — a count and a
     state, which are sentences about the deck and not identifiers. */
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  /* The mock's fixture chip reads "1 blocking" and never wraps. The product's
     own labels are longer — "No frames to check", "3 released over" — and a
     two-line chip inside a 46px plate is a broken plate. Named divergence:
     the chassis is the mock's, the wrap is refused. */
  white-space: nowrap;
}
.bench > .plate .chip i { width: 6px; height: 6px; border-radius: 50%; background: var(--readout-dim); flex: none }
.bench > .plate .chip.flag { color: #FF9AC8; border-color: #7A2B55 }
.bench > .plate .chip.flag i { background: var(--flag) }
.bench > .plate .chip.soft { color: #E9B7CF; border-color: #5E4053 }
.bench > .plate .chip.soft i { background: none; border: 1.5px solid var(--flag-soft) }
.bench > .plate .chip.clear { color: var(--beam-frame); border-color: #1E5C58 }
.bench > .plate .chip.clear i { background: var(--beam-frame) }
.bench > .plate .chip:hover { background: var(--frame-2) }
.lens { display: flex; border: 1px solid var(--frame-line); border-radius: 6px; overflow: hidden }
.lens button {
  background: none;
  border: 0;
  color: var(--readout-dim);
  cursor: pointer;
  width: 30px;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0;
}
.lens button.on { background: var(--frame-2); color: var(--beam-frame) }
.lens button:hover:not(.on) { color: var(--readout-hi) }
/* "Release · PNG", and "Developing 3/7" while it runs. Button text, so it is
   the UI sans. The uppercase carried the weight of a hero verb and is gone, so
   the weight is stated: 600 is what separates this from the prose around it
   now. */
.release {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  color: var(--readout-hi);
  padding: 6px 13px;
  cursor: pointer;
}
.release:hover { background: var(--frame-2); border-color: #5A5468 }
/*
 * The sign-off, hero per `2026-08-12-studio-ia.md` and previously at position
 * six of fifteen inside the `···`.
 *
 * `.release`'s type, and deliberately NOT its border. Two outlined uppercase
 * buttons side by side compete for the same glance, and the spec is explicit
 * that nothing may join the plate's primary and compete with it. So this is the
 * quiet one: same silhouette, no box, and it lights on hover. The border is
 * kept and made TRANSPARENT so the two sit on the same metrics — a transparent
 * border is not a box and `e2e/lib/calm.ts` does not count one.
 *
 * It is NOT hidden at phone widths the way `.release` is. Everything the plate
 * drops below 900px has a home in the menu; this has none, because a second
 * copy under the same name is the defect that was just removed from it.
 */
.signoff {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--readout-lo);
  padding: 6px 10px;
  cursor: pointer;
}
.signoff:hover { color: var(--readout-hi); background: var(--frame-2) }
.release[aria-disabled="true"] { opacity: .34; cursor: not-allowed }
.release[aria-disabled="true"]:hover { background: none; border-color: var(--frame-line) }
.iconbtn {
  background: none;
  border: 0;
  color: var(--readout);
  cursor: pointer;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  padding: 0;
}
.iconbtn:hover { background: var(--frame-2); color: var(--readout-hi) }
/* A colour, not a filter. At .3 the glyph was not dimmed, it was gone —
   and this is the seventh stylesheet in the tree carrying its own disabled
   rule, each with a different number. */
.iconbtn[disabled] { opacity: 1; color: #6b6579; cursor: not-allowed }
.iconbtn[disabled]:hover { background: none }

/* menus: secondary commands live one level down, never on the surface */
.bench .menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: #FFFDF9;
  border: 1px solid var(--note-line);
  border-radius: 10px;
  padding: 6px;
  min-width: 250px;
  box-shadow: 0 3px 8px rgba(23, 21, 28, .08), 0 14px 40px rgba(23, 21, 28, .18);
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s ease-out, visibility .12s;
  z-index: 55;
  max-height: min(72vh, 560px);
  overflow: auto;
}
.bench .menu.open { opacity: 1; visibility: visible }
.bench .menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  font-family: var(--sans);
  font-size: 13px;
  color: #211D28;
  padding: 7px 9px;
  border-radius: 6px;
  cursor: pointer;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.35;
}
.bench .menu button:hover { background: #F1EEE6 }
/* The figure beside a menu item's name: "5 frames", "one file", "link",
   "account", the lights mode. Words, so the UI sans — and "⌘Z" and "390 × 844"
   ride the same span and lose nothing by it, because a shortcut hint is read
   once and never compared character by character. The class keeps its name
   because `Bench.tsx`, `BenchCapsule.tsx` and `benchMenu.test.tsx` all name it,
   and renaming a class across three files is not this change. */
.bench .menu button .mono-aside {
  margin-left: auto;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--note-meta);
  letter-spacing: 0;
  white-space: nowrap;
}
.bench .menu .phone-only { display: none }
/* The menu's group headings — "Export and release", "Elsewhere", "Filing".
   Sans, sentence case and weighted, which is how a native menu separates its
   groups; 8.5px tracked uppercase was mono's way of surviving being that
   small, and the sans does not need it. */
.bench .menu .glab {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--note-meta);
  padding: 7px 9px 3px;
}
.bench .menu hr { border: 0; border-top: 1px solid #ECE9E0; margin: 5px 4px }

/* ---------- the stage: bench surface + one lit canvas ------------------- */
/* THE MIDDLE ROW: the stage, and whatever stands beside it.
   The stage was a direct child of the column. Comments needs to sit BESIDE the
   deck rather than over it, so the two share a row and the stage keeps `flex: 1`
   — opening the sidecar narrows the deck instead of hiding it. With no sidecar
   the row is a single flex child and the layout is exactly as it was. */
.benchmid {
  flex: 1;
  min-height: 0;
  min-width: 0;
  display: flex;
  position: relative;
  overflow: clip;
}

.carousel-assistant-context {
  display: grid;
  gap: 6px;
  padding: 0 0 12px;
  color: var(--ink-2);
  font-size: 13px;
  line-height: 1.45;
}
.carousel-assistant-context p { margin: 0 }
.carousel-assistant-context p:first-child {
  color: var(--ink);
  font-weight: 600;
}

.carousel-assistant-transcript-host {
  width: 100%;
  height: 100%;
  min-height: 0;
}

/* The comments sidecar. Paper against the bench's graphite, so it reads as a
   sheet laid on the bench rather than another slab of chrome. */
.benchside {
  flex: none;
  width: 100%;
  min-width: 0;
  display: flex;
  overflow: hidden;
  border-left: 1px solid var(--frame-line);
  background: var(--paper, #FBF8F2);
}
.benchside > * { width: 100%; min-width: 0 }

.stage {
  flex: 1;
  min-width: 0;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px 34px;
  background: var(--bench);
  touch-action: pan-y;
}
/* THE LIGHTS now span a real range: the lit bench, the instrument's own
   graphite (B1's original bench, kept as the state it always was), blackout.
   Every foreground on the stage swaps with it in one place. */
.bench[data-lights="dim"] {
  --bench: #1E1B26;
  --bench-lift: rgba(196, 190, 212, .10);
  --bench-ink: var(--readout-hi);
  --bench-ink-2: var(--readout-lo);
  --bench-line: rgba(255, 255, 255, .18);
}
.bench[data-lights="out"] {
  --bench: #0C0B11;
  --bench-lift: rgba(196, 190, 212, 0);
  --bench-ink: var(--readout-hi);
  --bench-ink-2: var(--readout-lo);
  --bench-line: rgba(255, 255, 255, .14);
}
.bench[data-lights="out"] .strip,
.bench[data-lights="out"] .plate { opacity: .12 }
.lightsout {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 14px;
  /* "Lights on · Esc", and the background-tab notice. A verb and a sentence. */
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  background: var(--frame);
  color: var(--readout-hi);
  border: 1px solid var(--frame-line);
  border-radius: 999px;
  padding: 6px 14px;
  z-index: 30;
  display: none;
  cursor: pointer;
}
.bench[data-lights="out"] .lightsout { display: block }

/* The canvas holder is only the flex box the artwork centres in. Contextual
   panels resize the StudioShell grid; the holder never moves for an overlay. */
.holder {
  position: relative;
  display: flex;
  align-items: stretch;
  max-height: 100%;
}

/* THE SPINE — the studio's left rail, at the WINDOW's edge.
   Its chassis is `src/design/toolrail.css`: width, glyph size, hit target,
   resting and hover colours, the news dot, the focus ring and where a rollover
   opens are all decided there, for both studios at once.

   It used to be bonded to the artwork — mounted inside `.holder`, taking the
   frame's corner radius and a seam on its right — which put it at x = 457 at
   1440 with 457px of dead grey to its left, riding the deck as the deck moved.
   It is now a direct flex child of `.benchmid`, so it starts at x = 0 and
   `.stage` takes what is left. Nothing here positions it: the position is
   structural, which is what makes it impossible to drift.

   So the bonded look goes with the bonding. No left border and no left radius
   — an edge of the window has no outside. */
.bench-page .spine {
  position: relative;
  min-height: 0;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scrollbar-width: none;
  border-right: 1px solid var(--spine-line);
}
.bench-page .spine::-webkit-scrollbar { display: none; }
/* Selected, the deck's NAME takes the beam and its ground does not. The 19px
   spine used to flood teal end to end; at 44px that is a teal slab, and the
   brightest thing on this page has to be the artwork. `toolrail.css` colours
   the lit name — this is only the edge agreeing with it. */
.bench[data-sel="deck"] .spine { border-right-color: var(--beam) }
.bench[data-lights="dim"][data-sel="deck"] .spine,
.bench[data-lights="out"][data-sel="deck"] .spine { border-right-color: var(--beam-frame) }

/* The stage and its sidecar, as one column pair beside the rail. This is the
   node that stacks on a phone — `.benchmid` must not, or the rail would become
   a horizontal bar across the top and stop being a left rail at the one width
   where screen space is scarcest. */
.benchcols {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  position: relative;
}

/* Properties is a real column in the studio anatomy. The stage keeps the
   remaining width, so selecting a control never paints over or unmounts the
   frame it changes. Cargo keeps the existing Bench control classes; the shared
   dock owns only the column, disclosure and responsive sheet. */
.bench-properties {
  width: 100%;
  height: 100%;
  min-width: 0;
  flex: 1;
  border-color: var(--c-hairline);
  container-type: inline-size;
}
.bench-properties:has(.bench-rule-book) {
  width: 100%;
  min-width: 0;
}
.bench-layers .studio-action-row {
  gap: 8px;
  padding-block: 4px;
}
.bench-layers .studio-action-row > button { min-height: 44px; }
.bench-properties-textarea {
  width: 100%;
  min-height: 88px;
  resize: vertical;
  border: 1px solid var(--frame-line);
  border-radius: 7px;
  padding: 9px 10px;
  background: var(--paper);
  color: var(--ink);
  font: 13px/1.45 var(--sans);
}
.decktitle {
  min-width: 0;
  max-width: min(34ch, 42vw);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* In the inspector, the phone's constraints matter and its ornamental device
   shell does not. The preview is a flat feed viewport; on an actual phone this
   avoids drawing a second rounded handset inside the handset in your hand. */
.bench-phone-preview figure[aria-label$="phone preview"] {
  max-width: none;
  border: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
}

@media (max-width: 900px) and (min-width: 641px) {
  .benchcols:has(> .bench-properties) { flex-direction: row }
}

.sgroup { border-top: 1px solid var(--spine-line); padding: 11px 0 2px }
.sgroup:first-of-type { border-top: 0 }
.sgroup > .lab {
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--readout-lo);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.pills { display: flex; flex-wrap: wrap; gap: 5px }
/* the same on/off grammar the plate's lens uses, so a chosen thing looks the
   same everywhere on the instrument */
.pill {
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--readout);
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  padding: 5px 10px;
  cursor: pointer;
}
.pill:hover { background: var(--frame-2); color: var(--readout-hi) }
.pill[aria-pressed="true"] { background: var(--frame-2); border-color: var(--beam-frame); color: var(--beam-frame) }
.swatches { display: flex; flex-wrap: wrap; gap: 6px }
.sw {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, .18);
  cursor: pointer;
  padding: 0;
}
.sw[aria-pressed="true"] { outline: 2px solid var(--beam-frame); outline-offset: 2px }
.srow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: none;
  border: 0;
  color: var(--readout);
  padding: 7px 6px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
  text-align: left;
  line-height: 1.35;
}
.srow:hover { background: var(--frame-2); color: var(--readout-hi) }
.srow em { font-style: normal; font-family: var(--mono); font-size: 9.5px; color: var(--readout-lo); white-space: nowrap }
.srow.door em { color: var(--beam-frame) }
.stoggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: none;
  border: 0;
  color: var(--readout);
  padding: 6px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
  text-align: left;
}
.stoggle:hover { background: var(--frame-2) }
.knob { width: 30px; height: 17px; border-radius: 999px; background: #514A63; position: relative; flex: none }
.knob::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: #BEB8CA;
  transition: transform .14s ease-out;
}
.stoggle[aria-pressed="true"] .knob { background: #0E5C57 }
.stoggle[aria-pressed="true"] .knob::after { transform: translateX(13px); background: var(--beam-frame) }
.brief {
  background: #211E2A;
  border: 1px solid var(--frame-line);
  border-radius: 7px;
  padding: 9px 10px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--readout);
  white-space: pre-line;
}
.brief .who {
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--readout-lo);
  display: block;
  margin-bottom: 5px;
}

/* ---------- the canvas -------------------------------------------------- */
.canvasbox { position: relative; flex: none; background: transparent }
/* THE CANVAS EDGE. On a lit bench the artwork's own ground can sit within a
   stop or two of the surround, so the edge is carried by a hairline and a
   shadow rather than by tone — the artboard rule every canvas tool uses.
   The hairline is outside the artwork, so it defines without tinting. */
.canvasbox .shadowwrap {
  position: relative;
  box-shadow:
    0 0 0 1px var(--bench-line),
    0 1px 2px rgba(23, 21, 28, .10),
    0 6px 14px rgba(23, 21, 28, .12),
    0 26px 62px rgba(23, 21, 28, .22);
}
.bench[data-sel="deck"] .shadowwrap::after {
  content: "";
  position: absolute;
  inset: -6px;
  border: 1.5px solid var(--beam);
  border-radius: 3px;
  pointer-events: none;
  z-index: 12;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .5);
}
.bench[data-sel="frame"] .shadowwrap::after {
  content: "";
  position: absolute;
  inset: -4px;
  border: 1.5px solid #57516A;
  border-radius: 2px;
  pointer-events: none;
  z-index: 12;
}
.bench[data-lights="dim"] .shadowwrap::after,
.bench[data-lights="out"] .shadowwrap::after { border-color: var(--beam-frame) }
.bench[data-lights="dim"][data-sel="frame"] .shadowwrap::after,
.bench[data-lights="out"][data-sel="frame"] .shadowwrap::after { border-color: #8F87A6 }

/* FREEZE-ON-EDIT: the first thing that MOVES an element writes every measured
   box into the frame and the column stops flowing. The product's own
   `SlideView` does the same job through `slide.free`; this rule is here
   because the mock declares it and because the ring below measures the
   result. */

/* selection on the canvas: a screen-pixel overlay measured from live DOM so
   handles never scale with the frame */
/* The ring and its handles ride over ARBITRARY brand artwork — cream, navy,
   sage — so a single tone can never carry them. The beam plus a light halo
   reads on every kit and on the lit bench, and it is B's beam, not a new
   colour. (The old bright beam-frame measured 1.34:1 on the cream kit.) */
.ring {
  position: absolute;
  pointer-events: none;
  z-index: 14;
  border: 1.5px solid var(--beam);
  border-radius: 1px;
  display: none;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .55), inset 0 0 0 1px rgba(255, 255, 255, .55);
}
.ring.on { display: block }
.ring.locked { border-style: dashed }
.ring.group { border-style: dashed; border-color: #57516A }
.h {
  position: absolute;
  width: 9px;
  height: 9px;
  background: var(--beam);
  border: 1.5px solid rgba(255, 255, 255, .75);
  border-radius: 2px;
  pointer-events: auto;
  z-index: 15;
}
/*
 * THE HANDLE IS 9px OF PAINT AND 21px OF TARGET.
 *
 * A 9px square is a quarter of the area a pointer is comfortable with, and it
 * is the control you are asked to hit precisely while the thing under it is
 * also draggable. The paint stays 9px — the ring is a hairline instrument and
 * fattening it would coarsen the whole canvas — and the target grows outward.
 *
 * `inset: -6px` and not a bigger box, because every pixel this grows INWARD is
 * a pixel stolen from the move gesture, which is the one the owner could not
 * land. Outward is free: it is the bench, and nothing else is there.
 */
.h::after {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: 5px;
}
.ring.locked .h { background: none }

/*
 * SMALL ELEMENTS: the handles get out of the body entirely.
 *
 * On a 38x30 swipe cue or a 25x12 frame number, eight handles at `-5px` put
 * resize targets across most of the element, so the press that was meant to
 * pick it up caught a handle instead. Below the threshold the four edge handles
 * go — a box this size is resized from a corner — and the corners move fully
 * outside the ring, which leaves the whole body as one uninterrupted move
 * target. The elements this affects are the furniture, which is exactly what
 * the owner was trying to drag.
 */
.ring.small .h.n, .ring.small .h.s, .ring.small .h.e, .ring.small .h.w { display: none }
.ring.small .h.ne { right: -14px; top: -14px }
.ring.small .h.se { right: -14px; bottom: -14px }
.ring.small .h.sw { left: -14px; bottom: -14px }
.ring.small .h.nw { left: -16px; top: -16px }
.h.nw { left: -5px; top: -5px; cursor: nwse-resize }
.h.n { left: calc(50% - 4.5px); top: -5px; cursor: ns-resize }
.h.ne { right: -5px; top: -5px; cursor: nesw-resize }
.h.e { right: -5px; top: calc(50% - 4.5px); cursor: ew-resize }
.h.se { right: -5px; bottom: -5px; cursor: nwse-resize }
.h.s { left: calc(50% - 4.5px); bottom: -5px; cursor: ns-resize }
.h.sw { left: -5px; bottom: -5px; cursor: nesw-resize }
.h.w { left: -5px; top: calc(50% - 4.5px); cursor: ew-resize }
/* the nw handle is the lock pip — a handle that carries its own control */
.h.nw {
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  width: 13px;
  height: 13px;
  left: -7px;
  top: -7px;
  color: #F4F2F8;
}
.h.nw svg { width: 8px; height: 8px; stroke: currentColor; fill: none; stroke-width: 2 }
.ring.locked .h.nw { background: var(--flag); color: #FFF; border-color: rgba(255, 255, 255, .75) }
/* the se handle carries the live readout during a gesture */
.hreadout {
  position: absolute;
  left: calc(100% + 8px);
  bottom: -6px;
  background: var(--frame);
  color: var(--beam-frame);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .04em;
  padding: 3px 7px;
  border-radius: 5px;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .1s ease-out;
  border: 1px solid var(--frame-line);
}
.hreadout.on { opacity: 1 }
.guide {
  position: absolute;
  background: var(--guide);
  z-index: 13;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .6);
}
/* the picture being framed: a dashed edge and no handles — nothing here
   resizes, and a handle that did nothing would be a promise the control
   cannot keep. */
.focusring {
  position: absolute;
  pointer-events: none;
  z-index: 14;
  border: 1px dashed var(--beam);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .5);
}
.focusmark { position: absolute; z-index: 15; pointer-events: none; color: var(--beam); mix-blend-mode: difference }

/* ===== THE SELECTION COMMAND SURFACE — one chassis, studio cargo =========
   The chassis is `.c-seltool` in `src/design/calm.css`, and the capsule wears
   it. Below is ONLY B1's cargo: where the bar is placed on a canvas, which way
   its menu opens, the pink finding verb, and the type-size stepper — a canvas
   verb with no counterpart in a writing surface, so it is assembled from the
   chassis's own button rather than imported as a widget.
   (z-index is B1's own stacking, where the strip sits at 20.) */
.seltool {
  display: flex;
  position: absolute;
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s ease-out, visibility .12s;
  transform: translateX(-50%);
  z-index: 26;
}
.seltool.open { opacity: 1; visibility: visible }
.seltool > button { font-family: var(--serif); font-size: 14px }
.seltool > button[aria-expanded="true"] { background: var(--frame-2); color: #fff }
/* the menu opens AWAY from the selection, never across it: when the bar sits
   above the object the menu goes up, when the bar sits below it goes down.
   B always opens downward because its bar is above a line of text; on a
   canvas that would drop the menu straight onto the thing you are changing.

   That preference is now `data-menu-side`, decided by `placeSelmenu`, and it is
   NOT `data-side`. The bar's side says where the selection is; it does not say
   whether a menu twice the bar's height clears the stage. Keyed off `data-side`
   a 69px menu followed a 37px bar off the top of an `overflow: hidden` stage and
   the ⋯ appeared to do nothing. */
.seltool .menu {
  right: auto;
  left: 50%;
  transform: translateX(-50%);
  top: auto;
  bottom: calc(100% + 8px);
  min-width: 250px;
}
.seltool[data-menu-side="below"] .menu { bottom: auto; top: calc(100% + 8px) }
/* the finding verb. Chassis-identical; the pink is the signature mark's own,
   and it is the only colour B1 puts on the bar. */
.seltool > button.why { color: var(--flag-frame) }
.seltool > button.why:hover { background: var(--frame-2); color: var(--flag-frame) }
.seltool > button.why.soft { color: var(--judge-frame) }
/* type size — a canvas verb with no counterpart in a writing surface, so it
   is assembled from the chassis button rather than imported as a widget */
.seltool .step { display: flex; align-items: center; gap: 2px }
.seltool .step button {
  background: none;
  border: 0;
  color: #C9C4D4;
  cursor: pointer;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  padding: 0;
  font-size: 14px;
  font-family: var(--sans);
}
.seltool .step button:hover { background: var(--frame-2); color: #fff }
.seltool .step .val {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--readout-lo);
  min-width: 36px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Exact controls opened by capsule verbs. Their cargo keeps the Bench's
   compact grids while StudioDock owns placement, disclosure and focus. */
.bench-choice-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}
.bench-choice-grid button,
.bench-context-toggles button {
  min-height: 38px;
  border: 1px solid var(--frame-line);
  border-radius: 8px;
  padding: 7px 9px;
  color: var(--muted);
  text-align: left;
  font-size: 12px;
  line-height: 1.25;
}
.bench-choice-grid button:hover:not(:disabled),
.bench-context-toggles button:hover:not(:disabled) { border-color: var(--frame-3); color: var(--ink) }
.bench-properties :is(button, input, textarea, select):disabled {
  cursor: not-allowed;
  opacity: .55;
}
.bench-choice-grid button[aria-pressed="true"],
.bench-context-toggles button[aria-pressed="true"] {
  border-color: var(--beam);
  color: var(--ink);
  box-shadow: inset 3px 0 0 var(--beam);
}
.bench-context-toggles {
  display: grid;
  gap: 6px;
  margin-top: 12px;
}
/* The type role of the selected text — "H1", "BODY". A name, not a value: it
   is never compared against another, so it is the UI sans. `Bench.tsx`
   uppercases the string itself, so the weight is what keeps it reading as a
   label rather than as a shout. */
.bench-role-name {
  margin: 0;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
}
.bench-role-scale {
  display: grid;
  gap: 8px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 11px;
}
.bench-role-scale input { width: 100%; accent-color: var(--beam) }
.bench-number-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}
.bench-number-field { display: grid; gap: 4px; color: var(--muted); font-size: 11px }
.bench-number-field input {
  min-width: 0;
  border: 1px solid var(--frame-line);
  border-radius: 7px;
  background: var(--paper);
  padding: 7px 8px;
  color: var(--ink);
  font: 12px var(--mono);
}
.bench-context-note { margin: 0 0 12px; color: var(--muted); font-size: 12px; line-height: 1.45 }
.bench-context-reset { margin-top: 12px; color: var(--muted); font-size: 12px; text-decoration: underline; text-underline-offset: 3px }
.bench-list-tools { display: grid; gap: 8px }
.bench-list-row { display: grid; grid-template-columns: minmax(0, 1fr) repeat(3, 30px); gap: 5px }
.bench-list-row input { min-width: 0; border: 1px solid var(--frame-line); border-radius: 7px; padding: 7px 8px; background: var(--paper); color: var(--ink) }
.bench-list-row button, .bench-list-add { border: 1px solid var(--frame-line); border-radius: 7px; color: var(--muted) }
.bench-list-add { min-height: 36px; padding: 7px 10px; text-align: left }
.bench-media-properties { display: grid; gap: 14px }
.bench-media-description { display: grid; gap: 6px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em }
.bench-media-description textarea { min-height: 72px; resize: vertical; border: 1px solid var(--frame-line); border-radius: 7px; background: var(--paper); padding: 8px; color: var(--ink); font: 13px/1.4 var(--sans); text-transform: none; letter-spacing: normal }
@container (max-width: 240px) {
  .bench-choice-grid { grid-template-columns: 1fr }
}

/* the finding note — the frame's voice, beside the capsule, never over the
   words it is about */
.fnote {
  position: absolute;
  z-index: 28;
  width: 296px;
  background: var(--note-bg);
  border: 1px solid var(--note-line);
  border-radius: 10px;
  padding: 13px 15px 12px;
  display: none;
  box-shadow: 0 1px 2px rgba(23, 21, 28, .05), 0 10px 30px rgba(23, 21, 28, .14);
}
.fnote.on { display: block }
/* "What needs attention" — the note's own heading, and the row the close
   button sits in. A sentence, so the UI sans at a size it can be read at. */
.fnote .prov {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--note-meta);
  margin-bottom: 7px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.fnote .prov .x {
  background: none;
  border: 0;
  color: var(--note-meta);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 4px;
}
.fnote .prov .x:hover { background: var(--surface-3); color: var(--ink) }
/*
 * THREE CONSTANTS, AND THE POPOVER'S GROUND IS A TOKEN.
 *
 * `--note-bg` follows the theme; these did not. In dark the panel painted
 * itself rgb(22,21,28) and this heading stayed #211D28 — the sentence naming
 * the exact words at fault, rendered at 1.10:1 on its own background, with
 * "How to fix it" and "Why" legible beneath it. Somebody read the remedy for a
 * problem they could not read, and acted on a guess about what was wrong.
 *
 * Measured on production, dark, 13.5px. Light was fine throughout, which is
 * why it survived: the constants were sampled from the light design and are
 * correct there and nowhere else.
 */
.fnote h4 { margin: 0 0 5px; font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; color: var(--ink) }
.fnote h4.stop { color: var(--flag) }
.fnote .rule { font-family: var(--serif); font-size: 13px; line-height: 1.5; color: var(--ink-2); margin: 0 0 8px }
.fnote .said {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0 0 9px;
  border-left: 2px solid var(--note-line);
  padding-left: 9px;
}
.fnote .acts { display: flex; gap: 5px; flex-wrap: wrap; border-top: 1px solid var(--note-line); padding-top: 9px }
.fnote .act {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  /* Both halves move together. This button sits ON `--note-bg`, which follows
     the theme, so a white chip with dark ink was the only light object left on
     a dark panel — and changing either one alone would have swapped a jarring
     button for an unreadable one. */
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--note-line);
  border-radius: 6px;
  padding: 5px 10px;
  cursor: pointer;
}
.fnote .act:hover { border-color: #B9B3C6 }
/*
 * WRITTEN FOR THE KEY HINT, AND IT CATCHES THE LABEL TOO.
 *
 * `BenchFnote.tsx` puts the action's NAME in a span and the key beside it in a
 * second span — `<span>Use this wording</span><span>⏎</span>` — so this rule
 * sets both, and `.act`'s own 12px/600/`--ink` reaches nothing. The names are
 * the majority of what renders here and they are prose, so this is the sans.
 * The key that rides with them loses nothing: a shortcut hint is read once,
 * never compared glyph by glyph.
 *
 * The size and the meta grey on an action's NAME are a separate defect and are
 * left as they are — fixing them means deciding a colour, which this pass does
 * not touch.
 */
.fnote .act span { font-family: var(--sans); font-size: 11px; color: var(--note-meta); font-weight: 500; margin-left: 5px }
.fnote .nowording { font-family: var(--mono); font-size: 9px; letter-spacing: .06em; color: var(--note-meta); align-self: center }

/* THE PINK SQUIGGLE on canvas text.
   NOT DRAWN HERE, and that is deliberate. The mock declares
   `::highlight(finding-stop)` / `::highlight(finding-hold)` in #D6006E and
   #E489B6 — but the product already paints it, in `src/slide/slide.css`, under
   the name `review-flag` and in `--color-flag-canvas` (#ff2e8e): a brighter
   magenta from the same signature family, picked to stay legible over
   ARBITRARY brand artwork rather than over one fixture's cream.
   `slide.css` is the file the exporter renders, so a second declaration here
   would be a second answer to "what does a finding look like on a frame" —
   and the one thing that must never happen is the preview and the PNG
   disagreeing. The signature survives; it is owned one level down.
   `slide.css` also owns the whole-field mark, keyed off `[data-flagged]` on the
   canvas wrapper, which is what `BenchCanvas` sets. */

/* in-place typing: the element becomes editable where it stands */
.bench .el-typing { box-shadow: 0 0 0 1.5px var(--beam-frame) }

/* ---------- the empty deck --------------------------------------------- */
/* the empty deck: the frame that is not there yet, drawn as latent paper */
/* the dash is the empty state's whole affordance, so it is drawn stronger
   than the canvas hairline, not the same */
.emptyframe {
  width: var(--sw);
  height: calc(var(--sw) * var(--ar));
  border: 1.5px dashed rgba(33, 29, 21, .55);
  border-radius: 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 13px;
  text-align: center;
  padding: 28px;
  background: rgba(251, 248, 242, .5);
}
.bench[data-lights="dim"] .emptyframe,
.bench[data-lights="out"] .emptyframe { background: rgba(255, 255, 255, .014); border-color: #5A5468 }
.emptyframe .g { color: var(--bench-ink-2) }
.emptyframe h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--bench-ink); letter-spacing: -.01em }
.emptyframe p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--bench-ink-2); max-width: 30ch }
/* the primary button is B's: graphite on a lit ground, never a teal fill */
.bigbtn {
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  color: #F0EEF4;
  background: var(--frame);
  border: 1px solid var(--frame);
  border-radius: 8px;
  padding: 9px 17px;
  cursor: pointer;
  margin-top: 3px;
}
.bigbtn:hover { background: var(--frame-2); border-color: var(--frame-2) }
.linkbtn {
  background: none;
  border: 0;
  color: var(--bench-ink-2);
  font-size: 12.5px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 2px;
}
.linkbtn:hover { color: var(--bench-ink) }

/* ---------- the caption surface: the last beat, on the canvas ---------- */
/* Only the caption body has to clear the fold tag in the right gutter. The
   card used to reserve that gutter for everything, which pushed the alt-text
   fields and the character line into a column too narrow for their content
   and clipped them mid-word. The gutter now belongs to the text the fold
   actually measures. */
/*
 * THE CAPTION SITS ON THE ARTWORK'S PAPER, NOT THE PAGE'S.
 *
 * It painted itself `--paper` — the PAGE's token, #F4F3F6 in light and
 * #0E0D12 in dark — while setting its text from `--p-ink` and `--p-meta`,
 * which are the ARTWORK's inks and exist to be read on cream. In light the
 * two grounds are close enough that nobody saw it. In dark the sheet went
 * near-black and kept the dark ink: the label above the caption measured
 * 3.4:1 at 9px, found by axe on the rendered page rather than by reading this.
 *
 * `--art-paper` is declared eleven hundred lines up for exactly this reason —
 * "the artwork's own, literal, because artwork is content" — and was wired to
 * nothing. The caption is what gets posted with the frames, so it is content
 * and it does not recolour with the chrome, the same way the frames do not.
 */
.captionsurface {
  width: 100%;
  background: var(--art-paper);
  color: var(--p-ink);
  border-radius: 6px;
  padding: 26px 26px 20px 26px;
  position: relative;
  box-shadow:
    0 0 0 1px var(--bench-line),
    0 1px 2px rgba(23, 21, 28, .10),
    0 6px 14px rgba(23, 21, 28, .12),
    0 26px 62px rgba(23, 21, 28, .22);
  max-height: 100%;
  /* Vertical only. The card is exactly as wide as it means to be; there is
     never anything to scroll sideways to, and allowing it turned a few pixels
     of overhang into a scroll area that then became the containing block for
     the thing overhanging it. */
  overflow-x: hidden;
  overflow-y: auto;
}
/* "The caption you post with these frames", and the platform it is read
   under. A sentence and a name, so the artwork's own sans. */
.captionsurface .who {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--p-meta);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.captionsurface .cap-body,
.captionsurface .tags { padding-right: 74px }
.captionsurface .cap-body { font-size: 15px; line-height: 25px; outline: none; position: relative }
/* The mock sets the hashtags in the fixture kit's own indigo. The product's
   accent is whatever a customer's brand says it is, and an arbitrary hex on
   #FBF8F2 paper is a contrast failure waiting for the first client whose brand
   colour is yellow. The beam was the other candidate and is worse: it means
   "affirmed" everywhere else in this system, and a hashtag is not affirmed by
   anything. So they take the caption's own secondary ink — distinct from the
   body, borrowing no meaning, 5.54:1 on paper. */
.captionsurface .tags {
  margin-top: 14px;
  font-size: 14px;
  line-height: 24px;
  color: var(--p-ink-2);
  outline: none;
}
/* THE FOLD: where the platform truncates the caption. A fact of the surface,
   drawn as one hairline with its reading out in the margin — it never covers
   a word.
   The mock hangs the reading OFF THE END of the hairline (`left: calc(100% +
   11px)` on a rule inset 100px from the right). That works on a specimen and
   not in a card that can scroll: the tag's own overhang becomes part of the
   scrollable area, which is then the box `100%` is measured against, which
   moves the tag further out again. Drawn INSIDE the rule and pinned to its
   right instead — the hairline now runs the full text column, and the tag sits
   in the same 74px gutter `.cap-body` already reserves, so it still covers no
   word and cannot escape the card. */
.fold {
  position: absolute;
  left: 26px;
  right: 26px;
  border-top: 1px dashed rgba(33, 29, 21, .24);
  pointer-events: none;
}
.fold .ftag {
  position: absolute;
  left: auto;
  right: 0;
  top: -7px;
  width: 74px;
  text-align: right;
  /* Artwork paper — see `.postcard`. This label sits on the caption sheet's
     fold, so it shares that sheet's ground and its ink. */
  background: var(--art-paper);
  /* "instagram cuts here · “…more”". A sentence about the platform, so sans —
     and 9.5px because it wraps inside a 74px gutter and must not take a fourth
     line doing it. */
  font-family: var(--sans);
  font-size: 9.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--p-meta);
  line-height: 1.5;
}
.altlist { margin-top: 20px; border-top: 1px solid var(--p-hairline); padding-top: 13px }
/* "Image descriptions · the fourth rule scope" — a section heading. */
.altlist .lab {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--p-meta);
  margin-bottom: 8px;
}
.altrow { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; line-height: 1.45; color: var(--p-ink-2); padding: 5px 0 }
/* "Frame 2 · photo" — which picture this description belongs to. A field
   label with an ordinal in it, not an identifier. */
.altrow b {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0;
  color: var(--p-meta);
  flex: none;
  width: 64px;
  padding-top: 2px;
  font-weight: 400;
}
.altrow input {
  flex: 1;
  border: 0;
  border-bottom: 1px solid var(--p-hairline);
  background: none;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--p-ink);
  padding: 2px 0;
  outline: none;
  text-overflow: ellipsis;
}
.altrow input:focus { border-bottom-color: var(--beam) }
/* "Caption · 412 characters" and "caption.txt travels with the PNGs". A count
   and a sentence — the file name inside the sentence is not being compared to
   anything, it is being told to you. */
.captionsurface .charline {
  margin-top: 14px;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0;
  color: var(--p-meta);
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

/* ---------- the strip: a rhythm graph that becomes thumbnails ---------- */
/* the strip is chrome, so it is the instrument's own graphite — the plate and
   the status readout wear the same value, and B1 no longer carries a third */
.strip {
  flex: none;
  background: var(--frame);
  position: relative;
  z-index: 20;
  transition: height .18s ease-out;
  height: 86px;
  overflow: hidden;
}
.strip[data-open="1"] { height: 190px }
.strip .inner {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 100%;
  padding: 24px 14px 8px;
  overflow-x: auto;
  overflow-y: hidden;
}
/* The tabs remain one semantic group while `display: contents` lets the add
   control and divider keep their physical place between frames and caption. */
.strip .tabs { display: contents }
.strip .tabs .beat.post { order: 3 }
.strip .heads {
  position: absolute;
  top: 0;
  left: 14px;
  right: 14px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* "The argument · 6 frames + caption" on the left, "bar height = words on
     the frame" on the right. Both are sentences explaining the strip. */
  font-family: var(--sans);
  font-size: 10.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  pointer-events: none;
  z-index: 2;
}
.beat {
  flex: none;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: stretch;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  width: 34px;
  transition: width .18s ease-out;
}
.strip[data-open="1"] .beat { width: 68px }
.strip[data-open="1"] .beat.post { width: 56px }
/* at rest the bar height IS the text density — the strip is the rhythm read */
.bar {
  height: var(--d);
  min-height: 5px;
  border-radius: 2px;
  background: #5B5470;
  transition: height .18s ease-out, background .12s ease-out;
}
.beat:hover .bar { background: #786F91 }
.beat[aria-current="true"] .bar { background: var(--readout-hi) }
.beat.post .bar { background: none; border: 1px solid #6B6484 }
.beat[aria-current="true"].post .bar { background: var(--readout-hi); border-color: var(--readout-hi) }
.beat .num {
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .06em;
  color: var(--readout-lo);
  text-align: left;
  padding: 5px 0 0;
  font-variant-numeric: tabular-nums;
}
.beat[aria-current="true"] .num { color: var(--readout-hi) }
.beat .pips { position: absolute; top: -9px; left: 0; display: flex; gap: 3px }
.pip { width: 6px; height: 6px; border-radius: 50% }
.pip.stop { background: var(--flag) }
.pip.hold { background: none; border: 1.5px solid var(--flag-soft) }
.beat .thumbwrap { display: none; position: relative; margin-bottom: 5px }
.strip[data-open="1"] .beat .thumbwrap { display: block }
/* expanded, the bar lies down: the same density read, now as a filled length
   under each frame instead of a standing bar */
.strip[data-open="1"] .bar {
  height: 3px;
  min-height: 3px;
  background: linear-gradient(90deg, #9A93AF 0 var(--dp), #443F52 var(--dp) 100%);
}
.strip[data-open="1"] .beat:hover .bar {
  background: linear-gradient(90deg, #BAB2CD 0 var(--dp), #443F52 var(--dp) 100%);
}
.strip[data-open="1"] .beat[aria-current="true"] .bar {
  background: linear-gradient(90deg, var(--readout-hi) 0 var(--dp), #443F52 var(--dp) 100%);
}
.strip[data-open="1"] .beat.post .bar { border: 0 }
.thumbwrap .frameborder { outline: 1px solid var(--frame-line); outline-offset: 0 }
.beat[aria-current="true"] .thumbwrap .frameborder { outline: 1.5px solid var(--beam-frame) }
.beat .grip {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  background: rgba(23, 21, 28, .78);
  color: #BEB8CA;
  display: none;
  place-items: center;
  z-index: 3;
  touch-action: none;
}
.strip[data-open="1"] .beat:hover .grip { display: grid }
.beat.dragging { opacity: .4 }
.dropmark {
  position: absolute;
  top: 24px;
  bottom: 26px;
  width: 2px;
  background: var(--beam-frame);
  border-radius: 2px;
  display: none;
  z-index: 5;
  pointer-events: none;
}
.dropmark.on { display: block }
.postcard {
  width: 100%;
  /* Artwork paper, not the page's. Same defect as `.captionsurface`: this
     paints a ground that follows the theme and then sets `--p-*` inks on it,
     which exist to be read on cream. In dark it went near-black and kept the
     dark ink. Found by axe on the rendered page at 8px, 3.4:1. */
  background: var(--art-paper);
  border-radius: 2px;
  padding: 5px;
  font-size: 5px;
  line-height: 1.35;
  color: var(--p-ink-2);
  overflow: hidden;
  height: 70px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* "Caption", on the thumbnail that stands for the post copy. */
.postcard b {
  font-family: var(--sans);
  font-size: 5.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--p-meta);
  font-weight: 600;
}
.postcard .tag { color: var(--p-ink-2) }
.stripadd {
  order: 1;
  flex: none;
  width: 34px;
  align-self: flex-end;
  height: 26px;
  border-radius: 4px;
  background: none;
  border: 1px dashed #5B5470;
  color: var(--readout-lo);
  cursor: pointer;
  display: grid;
  place-items: center;
  margin-bottom: 16px;
}
.strip[data-open="1"] .stripadd { height: 82px; width: 44px; margin-bottom: 22px }
.stripadd:hover { border-color: #8B84A0; color: var(--readout-hi) }
.stripadd[disabled] { opacity: .35; cursor: not-allowed }
.stripsep { order: 2; flex: none; width: 1px; align-self: stretch; background: var(--frame-line); margin: 22px 6px 20px }

/* ---------- bottom plate: the status readout --------------------------- */
.status {
  background: var(--frame);
  color: var(--readout);
  flex: none;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 18px;
  /* Everything in this bar is a sentence about the deck: what the check found,
     what is selected, how many frames and rules are in force, what this seat
     may do. None of it is an identifier, so none of it is mono. */
  font-family: var(--sans);
  font-size: 12.5px;
  position: relative;
  z-index: 22;
  border-top: 1px solid #17151C;
}
.status .sentence { display: flex; align-items: center; gap: 9px; letter-spacing: .01em; color: #C9C4D4; min-width: 0 }
.status .sentence > span { overflow: hidden; text-overflow: ellipsis }
.status .sentence i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--beam-frame);
  display: block;
  flex: none;
  opacity: 0;
  transition: opacity .24s ease-out;
}
.status .sentence.reading i { opacity: 1; animation: bench-breathe 1.2s ease-in-out infinite }
@keyframes bench-breathe { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
.status .sentence.clear { color: var(--beam-frame) }

/*
 * THE CHECK VERB, INSIDE THE SENTENCE IT ANSWERS.
 *
 * `flex: none` for the reason the deck-wide offer above carries the same
 * declaration: every member of `.status` is `nowrap`, and a flex item that can
 * shrink below its content overlaps its neighbour rather than ellipsing. The
 * sentence beside it already gives way — it is also in the header chip.
 *
 * It does not inherit `.sentence`'s colour. `.clear` turns that green and
 * `.reading` breathes it, and a verb that changes colour with the state of the
 * answer beside it reads as part of the readout rather than as something to
 * press.
 */
.status .platecheck {
  flex: none;
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-hi);
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
  cursor: pointer;
}
.status .platecheck:hover:not([disabled]) { background: var(--frame-2); border-color: #5A5468 }
/* The one state with something to say. The deck moved on and the answer beside
   this button is about words that are no longer on the frames. */
.status .platecheck.urgent { color: var(--beam-frame); border-color: var(--beam-frame) }
.status .platecheck[disabled] { opacity: 1; color: #8d87a0; cursor: default }
.status .selread {
  font-size: 11.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  border: 1px solid var(--frame-line);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
  /* `nowrap` with no `overflow` spills rather than shrinks: squeezing the box
     leaves the letters exactly where they were, on top of the neighbour. Both
     pills hold their width and the two prose readouts give way instead. */
  flex: none;
  background: none;
  cursor: pointer;
}
.status .selread:hover { color: var(--readout-hi); border-color: #5A5468 }
.status .aux {
  margin-left: auto;
  font-size: 11.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* `overflow: hidden` alone does nothing to a flex item: `min-width: auto`
     holds it at its content width and it overlaps its neighbour instead. */
  min-width: 0;
}

/* ---------- release decision cargo ------------------------------------- */
/* StudioDock owns the surface, title, dismissal and scrolling. This component
   is only the governed decision path that fills the dock cargo area. */
.release-cargo {
  width: 100%;
  min-width: 0;
  min-height: 100%;
  background: var(--frame);
}
.release-cargo .cerwrap { padding: 18px 16px 96px }
.release-cargo .contact { margin-bottom: 18px }
.release-cargo .ceremony-summary { font-size: 20px; text-align: left }
.release-cargo .cerwrap .eyebrow2,
.release-cargo .cerwrap .lede { text-align: left }
.release-cargo .fact { display: block }
.release-cargo .fact .k { width: auto; margin-bottom: 4px }
.release-cargo .cerfoot {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin: 18px -16px -96px;
  padding: 14px 16px 18px;
  background: var(--frame);
  border-top: 1px solid var(--frame-line);
}
.cerwrap { max-width: 620px; margin: 0 auto; padding: 46px 24px 60px }
.contact { display: flex; gap: 5px; justify-content: center; margin-bottom: 30px; flex-wrap: wrap }
.contact .cf { width: 38px; outline: 1px solid var(--frame-line); position: relative }
.contact .cf .pipdot { position: absolute; top: -6px; right: -3px; width: 6px; height: 6px; border-radius: 50% }
.contact .cf .pipdot.stop { background: var(--flag) }
.contact .cf .pipdot.hold { background: none; border: 1.5px solid var(--flag-soft) }
.contact .cpost {
  width: 38px;
  height: 47px;
  /* Artwork paper — see `.postcard`. */
  background: var(--art-paper);
  outline: 1px solid var(--frame-line);
  display: grid;
  place-items: center;
  /* One word — "caption" — on a 38px contact-sheet tile. */
  font-family: var(--sans);
  font-size: 7px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--p-meta);
}
/* "Approval", "Release · PDF", "How this is read" — what the ceremony below
   it is. A name for a section, so the UI sans. */
.cerwrap .eyebrow2 {
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  text-align: center;
}
/* The detailed release sentence is cargo copy; StudioDock owns the one heading. */
.ceremony-summary {
  font-size: 27px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--readout-hi);
  text-align: center;
  margin: 10px 0 6px;
  line-height: 1.2;
}
.cerwrap .lede { text-align: center; font-size: 13px; line-height: 1.6; color: var(--readout-lo); margin: 0 auto 28px; max-width: 52ch }
.facts { border-top: 1px solid var(--frame-line) }
.fact { display: flex; gap: 14px; align-items: flex-start; padding: 12px 2px; border-bottom: 1px solid var(--frame-line) }
/* The left half of a record row: "The approval", "Total rules", "Needs a
   person", "Signed off outside". Field labels, and the 112px column takes them
   at 12px sans as readily as it took uppercase mono at 9. */
.fact .k {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  width: 112px;
  flex: none;
  padding-top: 3px;
}
.fact .v { font-size: 13.5px; line-height: 1.5; color: #CFC9DC; flex: 1 }
.fact .v b { color: var(--readout-hi); font-weight: 600 }
/*
 * THREE TONES, AND ONLY ONE OF THEM IS MAGENTA.
 *
 * `.fact.flagged` was one class carrying eleven different facts — a stale
 * read, two rules that contradict each other, a waiver somebody recorded, an
 * acceptance that lapsed, a sign-off that ended when the words changed, a
 * release that will not reach the register, a release with no name on it — and
 * it painted every one of them `#FF9AC8`. The colour law gives magenta three
 * jobs: a finding that stops a release, the squiggle under the phrase it
 * caught, and the count of those. It names a waiver and a date among the
 * things it is never for.
 *
 * So the class is split by what the row MEANS. `.stop` is the one row that is
 * a finding stopping a release. `.judge` is every row where a person has to
 * decide or has already decided — which is what `--judge` is for, and what
 * `settings_account()` in `pitch.py` reached for when it had the same problem
 * with overridden rules. `.cleared` is unchanged.
 */
.fact.stop .v b { color: #FF9AC8 }
.fact.judge .v b { color: #C6AEF4 }
.fact.cleared .v b { color: var(--beam-frame) }
.fact .v .sub2 { display: block; font-size: 11.5px; color: var(--readout-lo); margin-top: 3px; line-height: 1.5 }
.decide { margin-top: 9px; border: 1px solid var(--frame-line); border-radius: 9px; padding: 11px 13px; background: #211E2A }
.decide .dq { font-size: 12.5px; color: #CFC9DC; margin: 0 0 9px; line-height: 1.5 }
.decide .dq em { font-style: normal; font-family: var(--serif); color: var(--readout-hi) }
.decide textarea {
  width: 100%;
  background: #1B1924;
  border: 1px solid var(--frame-line);
  border-radius: 7px;
  color: var(--readout-hi);
  font-family: var(--sans);
  font-size: 12.5px;
  padding: 8px 10px;
  min-height: 56px;
  resize: vertical;
  outline: none;
}
.decide textarea:focus { border-color: var(--beam-frame) }
.classes { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 9px }
.classbtn {
  font-size: 11.5px;
  color: var(--readout);
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 7px;
  padding: 6px 10px;
  cursor: pointer;
  text-align: left;
  line-height: 1.3;
}
.classbtn:hover:not([disabled]) { background: var(--frame-2); color: var(--readout-hi) }
/* a disabled control still has a body — it is waiting, not absent */
.classbtn[disabled] { background: #211E2A; color: var(--readout-lo); border-color: #332F3D; cursor: not-allowed }
.classbtn span { display: block; font-size: 9.5px; color: var(--readout-lo); margin-top: 2px }
.binding { margin-top: 22px; background: #211E2A; border: 1px solid var(--frame-line); border-radius: 10px; padding: 15px 17px }
/* "The record", "What the record will say, verbatim" — the heading over the
   words that are about to be written down. */
.binding .lab {
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout-lo);
  margin-bottom: 8px;
}
.binding p { margin: 0; font-family: var(--serif); font-size: 14.5px; line-height: 1.62; color: #D8D2E4 }
.ack { display: flex; gap: 11px; align-items: flex-start; margin-top: 18px; cursor: pointer; font-size: 13px; line-height: 1.5; color: #CFC9DC }
.ack input { margin-top: 3px; width: 16px; height: 16px; accent-color: #22E0D5; flex: none }
.cerfoot { display: flex; gap: 9px; align-items: center; margin-top: 20px; flex-wrap: wrap }
.gobtn {
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  color: #0F1A19;
  background: var(--beam-frame);
  border: 0;
  border-radius: 8px;
  padding: 10px 18px;
  cursor: pointer;
}
.gobtn[aria-disabled="true"] { background: var(--frame-2); color: #ADA6BC; cursor: not-allowed }
.cerfoot .note2 { font-size: 11.5px; color: var(--readout-lo); flex-basis: 100%; line-height: 1.5 }
/* The deck-wide offer, in the status plate beside the sentence it follows.
   Quiet until the verb it belongs to has just run, and gone by the next one. */
/*
 * THE OFFER IS THE THING BEING ASKED, SO IT KEEPS ITS ROOM.
 *
 * Seen on a real bench at 1440: "Match this size on the 3 that can take it?"
 * ran straight through the selection readout beside it and the two sets of
 * letters overlapped. Every member of `.status` is `nowrap` and a flex item's
 * default `min-width: auto` refuses to shrink below its content, so the row
 * simply overflowed into itself — invisible while the only offer in the product
 * was the four short words `hide` raises.
 *
 * `flex: none` here and `min-width: 0` on the two readouts that CAN be
 * shortened: the plate's sentence is also on screen in the header chip, and
 * `.aux` is a list of facts that already ellipses. The offer is the only one of
 * the four that a person has to read in full to answer.
 */
.deckoffer {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  flex: none;
  /* The offer is a question put to the reader, and the button beside it is the
     answer. Both are words, so both are the UI sans. */
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--readout);
  white-space: nowrap;
}
.deckoffer button {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--beam-frame);
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  padding: 4px 9px;
  cursor: pointer;
}
.deckoffer button:hover { background: var(--frame-2); color: #fff }

/* Generic door dialog for the labelled doors.
 *
 * SCOPED TO `.bench-page`, WHICH IS THE ONLY PLACE IT DRAWS.
 *
 * `.door` was declared bare here, and this file is loaded on every signed-in
 * route the moment `Bench.tsx` is in the bundle. `pitch.css`'s Make board
 * names its two halves `.door` as well (`.tMake.ppboard .door`) and says
 * nothing about `position`, `inset`, `z-index` or `align-items` — so on the
 * ported Make screen both doors laid out as full-viewport modal scrims
 * stacked at 0,0 with every child centred, and the two-column grid drew
 * nothing (P2-Make report, §2C).
 *
 * Every element that carries this class is inside `.bench-page`:
 * `BenchDoors.tsx:89` (`DoorCard`, imported only by `Bench.tsx:84`) and
 * `Bench.tsx:2700`, both under the root at `Bench.tsx:1774`. The `.on` state
 * is scoped with it — a bare `.door.on` asserting `display: flex` over a
 * ported screen's door is the same leak one class further along. */
.bench-page .door { position: absolute; inset: 0; z-index: 66; background: rgba(23, 21, 28, .52); display: none; align-items: center; justify-content: center; padding: 24px }
.bench-page .door.on { display: flex }
.doorcard {
  background: #FFFDF9;
  border-radius: 12px;
  max-width: 520px;
  width: 100%;
  padding: 22px 24px;
  box-shadow: 0 4px 10px rgba(23, 21, 28, .14), 0 28px 70px rgba(23, 21, 28, .3);
  max-height: 100%;
  overflow: auto;
}
/* "Release", "The record", "Elsewhere", "Archived" — which room this door
   opens onto, above its own heading. */
.doorcard .eyebrow3 { font-family: var(--sans); font-size: 11.5px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--note-meta) }
.doorcard h3 { margin: 8px 0 8px; font-size: 19px; font-weight: 600; letter-spacing: -.02em; color: #1B1826 }
.doorcard p { margin: 0 0 11px; font-size: 13.5px; line-height: 1.6; color: #4A4655 }
.doorcard ul { margin: 0 0 12px; padding-left: 18px; font-size: 13px; line-height: 1.6; color: #4A4655 }
.doorcard .close {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: #F0EEF4;
  background: var(--frame);
  border: 0;
  border-radius: 7px;
  padding: 8px 15px;
  cursor: pointer;
}

/* A door whose room is a real component rather than a card of prose. The
   rooms are the audit's own dialogs — the brand kit, the rule book, the
   review list, the composer — and they draw their own chrome, so the door
   gives them the scrim and gets out of the way. */
.doorroom {
  position: absolute;
  inset: 0;
  z-index: 66;
  display: flex;
  overflow: auto;
  /*
   * THE SCRIM AND THE GROUND, which the comment above has always promised and
   * this rule never gave.
   *
   * The composer's own root is `flex h-full w-full flex-col` with no
   * background of its own — it inherited one from the editor this bench
   * replaced. With a transparent room it rendered full-bleed and see-through:
   * headings over the plate, starter chips over the filmstrip, a bare textarea
   * across the middle of the deck. The owner's words were "hit the pencil
   * button and it shit the bed", and he was right.
   *
   * Paper, because a room in this studio is paper — the same ground the
   * caption card and the ceremony stand on.
   */
  background: var(--paper, #FBF8F2);
}

/* live region */
.live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0) }

/* ---------- responsive: 390px is a real target ------------------------- */
@media (max-width: 900px) {
  /* Below this the deck and an inspector sheet genuinely do not both fit, so the
     row stacks and the sidecar takes the width under a shortened stage. The
     deck still narrows rather than disappearing, which is the whole point of
     moving comments out of the door. */
  /* The COLUMNS stack; the rail does not. `.benchmid` stays a row so the rail
     keeps its 44px at the left edge — see `.benchcols`. */
  .benchcols { flex-direction: column }
  .benchside { width: auto; flex: 1 1 45%; border-left: 0; border-top: 1px solid var(--frame-line) }

  .plate { gap: 6px; padding: 0 6px 0 10px; font-size: 11.5px; letter-spacing: 0 }
  .plate .crumb { flex: 1 1 auto; min-width: 0 }
  .plate .crumb b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0 }
  .plate .crumb .brandname, .plate .unsaved { display: none }
  .plate .rhs { gap: 2px; flex: none }
  /* the phone plate keeps the check and one menu; everything else moves in */
  .plate .lens, .plate .histbtn, .plate .release { display: none }
  /* The sign-off STAYS where `.release` goes — it has no menu copy to fall
     back on — but it pays for its place with tighter metrics. */
  .signoff { padding: 6px 6px; font-size: 11.5px }
  .bench > .plate .chip { padding: 4px 9px; white-space: nowrap }
  .bench .menu .phone-only { display: flex }
  .stage { padding: 12px; align-items: flex-start }
  /* the bar keeps its chassis on a phone; it pins above the strip and WRAPS
     its verbs. It must never scroll: a scroll container clips its own popover,
     and the ⋯ menu hangs outside the bar's box. */
  .bench-page .seltool {
    left: 8px !important;
    right: 8px !important;
    bottom: 8px;
    top: auto !important;
    transform: none !important;
    justify-content: center;
    flex-wrap: wrap;
    row-gap: 2px;
    gap: 1px;
    z-index: 50;
  }
  .bench-page .seltool .c-sep { margin: 0 2px }
  /* a tooltip fired by a tap is a tooltip that sits on the bar until you tap
     elsewhere. The aria-label still names every verb. */
  .bench-page .seltool [data-tip]::after { content: none }
  /* the phone changes the menu's WIDTH, not which way it opens — `bottom` was
     restated here and, sitting later in the file, it re-pinned the menu upward
     and undid the fits-test for every narrow viewport. */
  .bench-page .seltool .menu { left: 0; right: auto; transform: none; min-width: 0; width: 100% }
  /* the note stacks ABOVE the command bar rather than over it — the same
     move B makes to keep its note clear of the console */
  .fnote {
    left: 8px !important;
    right: 8px !important;
    bottom: 57px;
    top: auto !important;
    width: auto !important;
    z-index: 52;
    max-height: 58%;
    overflow: auto;
  }
  /* the strip's own header is desktop copy; on a phone the bars speak for
     themselves and the frame number stays */
  .strip { height: 70px }
  .strip[data-open="1"] { height: 122px }
  .strip .heads { display: none }
  .strip .inner { padding: 8px 10px 6px }
  .status { padding: 8px 10px; font-size: 11.5px; gap: 6px; flex-wrap: wrap }
  .status .sentence { flex: 1 1 auto; min-width: 0 }
  .status .selread { flex: none; font-size: 11px; padding: 3px 8px }
  .status .aux { display: none }
  .cerwrap { padding: 40px 16px 48px }
  .fact { flex-direction: column; gap: 3px }
  .fact .k { width: auto }
  .captionsurface { padding: 20px 18px 16px }
  .captionsurface .cap-body, .captionsurface .tags { padding-right: 0 }
  .fold { left: 18px; right: 18px }
}
@media (max-width: 640px) {
  .bench-properties:has(.bench-rule-book) {
    width: 100%;
    min-width: 0;
  }
}

/* The shared shell can be wide while the artifact track is not: at exactly
   1200px, Assistant + Properties leave the Bench roughly the room a phone
   would have. Respond to the track contract, not `window.innerWidth`, so the
   top plate and selection verbs remain reachable instead of clipping behind a
   rail. The normal 1024px docked layout has a wider artifact track and keeps
   its full chrome. */
.studio-shell[data-artifact-controls='compact'] .bench-page .plate {
  gap: 6px;
  padding: 0 6px 0 10px;
  font-size: 11.5px;
  letter-spacing: 0;
}
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .crumb .brandname,
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .unsaved,
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .lens,
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .histbtn,
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .release { display: none; }
.studio-shell[data-artifact-controls='compact'] .bench-page .plate .rhs { gap: 2px; }
.studio-shell[data-artifact-controls='compact'] .bench-page .bench .menu .phone-only { display: flex; }
.studio-shell[data-artifact-controls='compact'] .bench-page .seltool {
  left: 8px !important;
  right: 8px !important;
  bottom: 8px;
  top: auto !important;
  transform: none !important;
  justify-content: center;
  flex-wrap: wrap;
  row-gap: 2px;
  gap: 1px;
  z-index: 50;
}
.studio-shell[data-artifact-controls='compact'] .bench-page .seltool .c-sep { margin: 0 2px; }
.studio-shell[data-artifact-controls='compact'] .bench-page .seltool [data-tip]::after { content: none; }
.studio-shell[data-artifact-controls='compact'] .bench-page .seltool .menu {
  left: 0;
  right: auto;
  transform: none;
  min-width: 0;
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .bench-page *, .bench-page *::before, .bench-page *::after {
    transition: none !important;
    animation: none !important;
  }
}
.bench-comment-marker {
  position: absolute;
  z-index: 26;
  display: grid;
  width: 28px;
  height: 28px;
  place-items: center;
  border: 1px solid var(--line, #4b4657);
  border-radius: 999px;
  color: var(--beam, #20d9cf);
  background: var(--plate, #17151d);
  box-shadow: 0 4px 16px rgb(0 0 0 / 0.28);
}

.bench-comment-marker:hover,
.bench-comment-marker:focus-visible {
  border-color: currentColor;
}

/* A whole sentence: "Governing link unavailable for this canvas element.
   Select linked wording in Copy to edit it safely." */
.binding-state__unavailable {
  margin: 0 0 10px;
  color: var(--muted, #a9a2b8);
  font: 12px/1.45 var(--sans);
}

.slide-host[data-governed-binding-unavailable="true"] [data-el][aria-selected="true"] {
  outline: 1px dashed var(--beam, #20d9cf);
  outline-offset: 4px;
}

/* -------------------------------------------------------------------------
   THE SEAT STRIP — an ordinary refusal beside the work, never over it.
   The archived room keeps its door; a refused keystroke gets a status line
   anchored to the stage top with no scrim and no focus trap.
   ------------------------------------------------------------------------- */
.bench-seat-stop {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  max-width: min(560px, calc(100% - 24px));
  padding: 10px 12px;
  border: 1px solid var(--line-strong, var(--c-frame-line, #4a4556));
  border-radius: var(--radius-panel, var(--c-r-card, 10px));
  background: var(--surface, var(--c-frame-2, #37333f));
  color: var(--ink, var(--c-readout-hi, #f4f2f8));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
}
/* "Your seat", or "Governed Carousel" — what kind of refusal this is. */
.bench-seat-stop__eyebrow {
  font: 600 11.5px/1.2 var(--sans, ui-sans-serif, system-ui, sans-serif);
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-readout-dim, #9f9aab);
}
.bench-seat-stop__title { font-size: 13px; line-height: 1.35 }
.bench-seat-stop__line { flex-basis: 100%; font-size: 12px; line-height: 1.4; color: var(--c-readout-dim, #9f9aab) }
.bench-seat-stop__dismiss {
  margin-left: auto;
  min-height: 44px;
  min-width: 44px;
  padding: 0 12px;
  border: 1px solid var(--line-strong, var(--c-frame-line, #4a4556));
  border-radius: var(--radius-panel, var(--c-r-card, 10px));
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.bench-seat-stop__dismiss:focus-visible { outline: 2px solid var(--beam-frame, #22e0d5); outline-offset: 2px }

/*
 * The instruction, still on screen while the work runs.
 *
 * The composer clears the moment the request is sent, so all that was left was
 * a progress line and the person could not see what it was working on. Set
 * quieter than the progress sentence beneath it: it is context for the wait,
 * not the answer.
 */
.assistant-asked {
  margin: 0 0 6px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-3);
  font-style: italic;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* ---------- the canvas viewport (preview-only zoom and pan) --------------
   Owned by `CanvasViewportControls.tsx` and the `.canvas-viewport` wrapper in
   `BenchCanvas.tsx`. Everything in this file is how the frame is LOOKED AT;
   none of it may change what the frame is, exports as, or shows the strip.

   THE TRANSFORM IS NEVER ANIMATED. The ring, the guides and the focus outline
   are measured off live client rects in layout effects — a transform in
   transit would hand them mid-flight rects and park the ring beside the
   element. So the pan lands in one frame for everyone, and the reduced-motion
   block below keeps that a promise rather than an accident. */

.canvas-viewport {
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .canvas-viewport,
  .canvas-viewport-controls {
    transition: none;
  }
}

/* The stage grabs a pan by the frame's own ground once the content overflows;
   the cursor says so before the press does. */
.canvas-viewport[data-pannable='true'] .slide-host {
  cursor: grab;
}
.canvas-viewport[data-panning='true'] .slide-host {
  cursor: grabbing;
}

/* ---------- the zoom cluster ---------------------------------------------
   Chrome in the stage's own pixels, bottom right, in the strip's instrument
   language: mono, hairline, pill. Never over the sheets on a phone — the
   canvas owns the top of the stage there, so the cluster rides top right. */
.canvas-viewport-controls {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 30;
  display: flex;
  align-items: center;
  background: var(--frame, #26232e);
  border: 1px solid var(--frame-line, rgba(255, 255, 255, 0.16));
  border-radius: 999px;
  padding: 0 4px;
  box-shadow: 0 2px 10px rgba(23, 21, 28, 0.25);
}
.canvas-viewport-controls button {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--readout-lo, #a79fbc);
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  cursor: pointer;
}
.canvas-viewport-controls button:hover {
  color: var(--readout-hi, #f2effa);
}
.canvas-viewport-controls button[aria-pressed='true'] {
  color: var(--readout-hi, #f2effa);
}
.canvas-zoom-value {
  min-width: 48px;
  text-align: center;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--readout-hi, #f2effa);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 900px) {
  .canvas-viewport-controls {
    top: 10px;
    right: 10px;
    bottom: auto;
  }
}
/* ===========================================================================
 * THE TOOL RAIL'S CHASSIS
 *
 * Imported by `toolrail.tsx` itself, so a studio that adopts the component
 * cannot adopt it without its measurements. That is deliberate: the two rails
 * this replaces disagreed on width, glyph size, hit target, resting colour and
 * where the rollover opened, and every one of those disagreements was an
 * accident of which file somebody was editing.
 *
 * Every value here is a token both studios already define, at the same value:
 * `bench.css` and `instrument.css` both set `--frame: #2B2833`, `--frame-2:
 * #37333F`, `--frame-line: #443F4E`, `--readout-hi: #F4F2F8`, `--beam-frame:
 * #22E0D5` and the same `--sans` stack. The one exception is the news dot,
 * which asks for `--judge-frame` and falls back to the fascia's own
 * `--flag-soft` — see the note above `.railnews` for why. So this sheet
 * drops into either fascia unchanged, and a studio that later wants a different
 * graphite changes its token rather than this file.
 *
 * The measurements are `src/copy/Tools.tsx`'s, which is the rail that works.
 * =========================================================================== */

/* 44px is what eight glyphs cost the paper. The same eight as labelled rows
   would be a 220px panel arguing with the words — see the head of `Tools.tsx`
   for why this is icons and not a panel. */
.toolrail {
  flex: none;
  width: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 0;
  background: linear-gradient(90deg, var(--frame), var(--frame-2) 60%, var(--frame));
  border-right: 1px solid var(--frame-line);
  box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.04);
  z-index: 11;
}

.toolrail .railslot,
.toolrail .railhang {
  position: relative;
  display: block;
  flex: none;
}

.toolrail .railtool {
  position: relative;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: 6px;
  padding: 0;
  cursor: pointer;
  /* COMPUTED: `#A79FBC` on `--frame` `#2B2833` is 5.73:1, and on the gradient's
     lighter middle `--frame-2` `#37333F` is 4.87:1 — both clear AA for a 1.5px
     glyph stroke. Hover is `#F4F2F8` on `#37333F`, 11.07:1. Pressed is
     `#22E0D5` on `#37333F`, 7.43:1. */
  color: #a79fbc;
  transition: color 0.12s ease-out, background 0.12s ease-out;
}
.toolrail .railtool:hover,
.toolrail .railtool:focus-visible {
  background: var(--frame-2);
  color: var(--readout-hi);
}
 /* Refused: dimmed to say it will not act, and NOT hidden — the tooltip is
    the whole point of it still being there. It keeps its hover so the reason
    can be read. COMPUTED: `#6F6885` on `--frame` `#2B2833` is 3.02:1, which
    clears the 3:1 floor for a disabled-but-informative control. */
.toolrail .railtool[aria-disabled='true'] {
  color: #6f6885;
  cursor: default;
}
.toolrail .railtool[aria-disabled='true']:hover {
  background: none;
  color: #6f6885;
}

.toolrail .railtool[aria-pressed='true'] {
  background: var(--frame-2);
  color: var(--beam-frame);
}

/* News, as a dot rather than a number: a glyph has no room for a figure, and a
   control carrying a live count is never rare. The figure itself is in the
   rollover and in the accessible name, which is where a screen reader will
   find it — a dot says nothing to one.

   THE DOT'S COLOUR IS AN INSTRUMENT TOKEN, NOT A PAGE ONE. It painted from
   `--flag-soft`, which `instrument.css` and `platform.css` hold at the literal
   `#E489B6` chosen against graphite — but `bench.css` aliased it to `--judge`,
   a token `mock.css` picks against the PAGE and flips with the theme. In the
   light theme that is `#6D5B8F`, and on this rail's gradient (`--frame`
   `#2B2833` → `--frame-2` `#37333F` → `--frame`) it lands at 2.4:1 against
   the lightest stop — under the 3:1 floor a mark has to clear. `--judge-frame`
   is the value chosen for a ground that does not move. A fascia that has not
   minted one keeps its own literal rather than losing the dot to an undefined
   `var()`. */
.toolrail .railtool .railnews {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--judge-frame, var(--flag-soft));
}

.toolrail .railgap {
  width: 18px;
  height: 1px;
  background: var(--frame-line);
  margin: 6px 0;
  flex: none;
}

/* ---------------------------------------------------------------------------
 * THE ROLLOVER OPENS TO THE RIGHT, ONTO THE PAPER
 *
 * The rail is against the left edge of the window, so the default — centred
 * above — renders half off screen, and a tip on a strip this tall would open
 * near the ceiling hundreds of pixels from the pointer that asked for it.
 *
 * This does NOT ride either studio's `.tip-right` class, because `.tip-right`
 * means two different things depending on which stylesheet loaded: `calm.css`
 * anchors the tip at the element's own LEFT edge, `bench.css` tries to push it
 * BESIDE the element and then clobbers itself four lines later with a copy of
 * the `calm.css` rule. That is why the Bench spine's tooltip, which was added
 * precisely so the rail would explain itself, rendered ON TOP of the artwork it
 * sits beside. A shared chassis cannot ride a class whose meaning depends on
 * load order, so it states its own placement at a specificity that beats the
 * base rule in both sheets.
 * ------------------------------------------------------------------------- */
.toolrail .railtool[data-tip]::after,
.toolrail .railname[data-tip]::after {
  bottom: auto;
  right: auto;
  top: 50%;
  left: calc(100% + 9px);
  transform: translateY(-50%);
}

/* A constrained rail scrolls inside the studio's work row. Its old pseudo
   labels were children of that scrollport, so CSS clipped them at 44px even
   though the controls remained reachable. `ToolRail` now renders one fixed
   label from this same `data-tip` string; suppress the duplicate pseudo label
   without changing the required accessible name on the button. */
.toolrail[data-portal-tips='true'] .railtool[data-tip]::after,
.toolrail[data-portal-tips='true'] .railname[data-tip]::after {
  content: none;
}

.toolrail-portal-tip {
  position: fixed;
  z-index: 120;
  max-width: min(280px, calc(100vw - 24px));
  padding: 5px 9px;
  border-radius: 6px;
  background: #2b2833;
  color: #e7e4ee;
  box-shadow: 0 5px 18px rgb(23 21 28 / 28%);
  font-family: var(--sans, ui-sans-serif, system-ui, sans-serif);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.3;
  text-transform: none;
  white-space: normal;
  pointer-events: none;
  transform: translateY(-50%);
}
.toolrail-portal-tip[data-side='left'] { transform: translate(-100%, -50%); }

/* The subtle inner edge is the discoverability cue for more 44px actions.
   It belongs to the scrollport, not the filmstrip, and retires at either end. */
.toolrail[data-scroll-after='true'] {
  box-shadow:
    inset -1px 0 0 rgba(255, 255, 255, 0.04),
    inset 0 -16px 12px -12px rgba(167, 159, 188, 0.85);
}
.toolrail[data-scroll-before='true'] {
  box-shadow:
    inset -1px 0 0 rgba(255, 255, 255, 0.04),
    inset 0 16px 12px -12px rgba(167, 159, 188, 0.85);
}
.toolrail[data-scroll-before='true'][data-scroll-after='true'] {
  box-shadow:
    inset -1px 0 0 rgba(255, 255, 255, 0.04),
    inset 0 16px 12px -12px rgba(167, 159, 188, 0.85),
    inset 0 -16px 12px -12px rgba(167, 159, 188, 0.85);
}
/* Onto the chrome instead of onto the artwork, for a rail that is bonded to the
   thing it governs. On the Bench `right` puts a 250px label across the deck's
   own headline — measured, on the running browser, over the words "is on the". */
.toolrail[data-tips='left'] .railtool[data-tip]::after,
.toolrail[data-tips='left'] .railname[data-tip]::after {
  left: auto;
  right: calc(100% + 9px);
}

/* Once disclosure opens, its named panel supplies the visible identity. Touch
   browsers otherwise keep :hover latched and pin this label over that panel's
   title and first controls. The accessible name remains on the trigger. */
.toolrail .railtool[data-tip][aria-expanded='true']:hover::after,
.toolrail .railtool[data-tip][aria-expanded='true']:focus-visible::after,
.toolrail .railname[data-tip][aria-expanded='true']:hover::after,
.toolrail .railname[data-tip][aria-expanded='true']:focus-visible::after,
.toolrail .railtool[data-tip][aria-pressed='true']:hover::after,
.toolrail .railtool[data-tip][aria-pressed='true']:focus-visible::after,
.toolrail .railname[data-tip][aria-pressed='true']:hover::after,
.toolrail .railname[data-tip][aria-pressed='true']:focus-visible::after {
  opacity: 0;
  pointer-events: none;
}
/* ---------------------------------------------------------------------------
 * THE NAME OF THE OBJECT, DOWN THE EDGE
 * ------------------------------------------------------------------------- */
.toolrail .railname {
  flex: none;
  position: relative;
  width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 0;
  margin-bottom: 4px;
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  color: #a79fbc;
  transition: color 0.12s ease-out, background 0.12s ease-out;
}
/*
 * THE ONE PLACE ON THIS RAIL THAT KEEPS ITS TRACKED UPPERCASE, AND IT IS NOT
 * KEEPING MONO WITH IT.
 *
 * The word is the object's name — "Deck" — and a name is not an identifier, so
 * it is the UI sans like every other label in the product. What survives is the
 * spine treatment: rotated into `vertical-rl`, a single word set in caps with
 * 0.28em between the letters. That is what a name down the edge of a 44px rail
 * has to be. Sentence case reads as a mistake turned on its side, and without
 * the tracking the letters stack into a smear.
 *
 * 9.5px rather than 8.5px because the sans sets smaller caps than the mono did
 * at the same size, and the rail has the height to spare.
 */
.toolrail .railname .railnamelab {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}
.toolrail .railname:hover,
.toolrail .railname:focus-visible {
  background: var(--frame-2);
  color: var(--readout-hi);
}
/* Lit, the NAME takes the beam and the rail's ground does not. The Bench used
   to flood its whole 19px spine teal when the deck was selected; at 44px that
   is a teal slab, and the brightest thing on this page has to be the artwork.
   COMPUTED: `#22E0D5` on `#2B2833` is 8.73:1, on `#37333F` 7.43:1. */
.toolrail .railname.lit {
  color: var(--beam-frame);
}

/* ---------------------------------------------------------------------------
 * THE FOCUS RING, WHICH THIS FILE CANNOT ACTUALLY WIN — READ THIS BEFORE
 * "FIXING" IT
 *
 * Measured on the running browser, every control on this rail takes a `#0B756F`
 * ring: 2.61:1 against `--frame` and 2.22:1 against `--frame-2`, both under the
 * 3:1 WCAG 1.4.11 floor for a focus indicator, on a strip whose controls are
 * icons with no other label. The rule below does not change that and is not
 * pretending to — it is the correct value, parked so that it takes effect the
 * day the real cause is fixed.
 *
 * The cause is `index.css`, in `@layer base`:
 *
 *     :focus-visible:not(.copy-para, .slide [data-el]) {
 *       outline: 2px solid var(--color-beam) !important
 *     }
 *
 * whose `!important` is load-bearing — it exists to beat Tailwind's
 * `focus:outline-none`. `--color-beam` is darkened to `#0B756F` product-wide
 * because it was solved against the LIGHT surfaces, where it clears 4.53–5.54:1.
 * On graphite it does not, and every dark surface takes it: this rail, the
 * plate, the strip, the deck's settings column, the selection toolbar.
 *
 * NOTHING WRITTEN HERE CAN OVERRIDE IT. For important declarations the cascade
 * reverses layer order, so `@layer base` beats every later layer, and unlayered
 * styles sort LAST — which means an unlayered `!important` loses too. Verified
 * on the running browser by trying exactly that. `index.css` documents the same
 * trap twice, for `.copy-para` and for `.slide [data-el]`, and both had to be
 * added to that `:not()` list because there is no other lever.
 *
 * So the fix is a third exclusion in `index.css` plus a ground-aware ring, and
 * that is a product-wide contrast slice rather than a rail. It is why
 * `bench.css`'s own two-tone focus rule — written for precisely this reason
 * when the Bench was built — has never once applied.
 *
 * COMPUTED, for when it can apply: `--beam-frame` `#22E0D5` is 8.73:1 on
 * `#2B2833` and 7.43:1 on `#37333F`. The 2px offset is the bench's own.
 * ------------------------------------------------------------------------- */
.toolrail .railtool:focus-visible,
.toolrail .railname:focus-visible {
  outline: 2px solid var(--beam-frame);
  outline-offset: 2px;
}

/* A menu hung off one glyph opens beside it, level with it. What is inside is
   the studio's; where it lands is the rail's. */
.toolrail .railhang > :not(.railtool) {
  position: absolute;
  left: calc(100% + 8px);
  top: -6px;
  z-index: 36;
}
.studio-dock {
  display: flex;
  width: clamp(320px, 24vw, 360px);
  min-width: 320px;
  height: 100%;
  flex-direction: column;
  overflow: hidden;
  border-left: 1px solid var(--c-hairline, var(--color-ink-200));
  background: var(--c-paper, var(--color-ink-050));
  color: var(--c-ink, var(--color-ink-900));
}

.studio-dock--pane {
  height: 100%;
  max-height: none;
  border-radius: 0;
  box-shadow: none;
}

.studio-dock__header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  padding: 16px;
  border-bottom: 1px solid var(--c-hairline, var(--color-ink-200));
}

.studio-dock__close {
  grid-column: 2;
  grid-row: 1;
  width: 44px;
  height: 44px;
  border: 1px solid var(--c-hairline, var(--color-ink-300));
  border-radius: 7px;
  background: transparent;
  color: inherit;
  font: 400 22px/1 var(--c-sans, var(--font-sans));
  cursor: pointer;
}

.studio-dock__close:focus-visible {
  outline: 2px solid var(--c-beam, var(--color-beam));
  outline-offset: 2px;
}

.studio-dock__sheet-controls {
  display: none;
}

.studio-dock__title,
.studio-dock__subject {
  margin: 0;
}

.studio-dock__title {
  font: 600 12px/1.2 var(--c-sans, var(--font-sans));
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.studio-dock__subject {
  margin-top: 4px;
  color: var(--c-ink-2, var(--color-ink-500));
  font: 400 13px/1.35 var(--c-sans, var(--font-sans));
}

.studio-dock__tabs,
.studio-choice {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  padding: 2px;
  border: 1px solid var(--c-hairline, var(--color-ink-300));
  border-radius: 7px;
  background: var(--c-card, var(--color-ink-100));
}

.studio-dock__tab,
.studio-choice__option {
  min-height: 44px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--c-ink-2, var(--color-ink-500));
  font: 500 13px/1 var(--c-sans, var(--font-sans));
  cursor: pointer;
}

.studio-dock__tab[aria-selected='true'],
.studio-choice__option[aria-pressed='true'] {
  background: color-mix(in srgb, var(--c-beam, var(--color-beam)) 13%, transparent);
  color: var(--c-ink, var(--color-ink-900));
}

.studio-dock__tab:focus-visible,
.studio-choice__option:focus-visible,
.studio-dock__summary:focus-visible,
.studio-number-field:focus-visible {
  outline: 2px solid var(--c-beam, var(--color-beam));
  outline-offset: 2px;
}

.studio-dock__body,
.studio-dock__panel {
  min-height: 0;
}

.studio-dock__body {
  flex: 1;
  overflow-y: auto;
}

.studio-dock__panel[hidden] {
  display: none;
}

.studio-dock__section {
  border-bottom: 1px solid var(--c-hairline, var(--color-ink-200));
}

.studio-dock__summary {
  display: flex;
  min-height: 44px;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  color: var(--c-ink-2, var(--color-ink-500));
  font: 600 11px/1.2 var(--c-sans, var(--font-sans));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}

.studio-dock__summary::-webkit-details-marker {
  display: none;
}

.studio-dock__chevron {
  color: var(--c-meta, var(--color-ink-400));
  font-size: 16px;
  transform: rotate(0deg);
  transition: transform 150ms ease;
}

.studio-dock__section[open] .studio-dock__chevron {
  transform: rotate(90deg);
}

.studio-dock__section-body {
  display: grid;
  gap: 14px;
  padding: 2px 16px 16px;
}

.studio-field {
  display: grid;
  gap: 6px;
}

.studio-field__label {
  color: var(--c-ink-2, var(--color-ink-500));
  font: 600 11px/1.2 var(--c-sans, var(--font-sans));
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.studio-field__hint {
  color: var(--c-meta, var(--color-ink-400));
  font: 400 12px/1.4 var(--c-sans, var(--font-sans));
}

.studio-number-field {
  width: 100%;
  min-height: 36px;
  box-sizing: border-box;
  border: 1px solid var(--c-hairline, var(--color-ink-300));
  border-radius: 6px;
  background: var(--c-card, var(--color-ink-100));
  color: var(--c-ink, var(--color-ink-900));
  padding: 7px 9px;
  font: 400 14px/1.2 var(--c-sans, var(--font-sans));
}

.studio-action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.studio-action-row > button {
  min-height: 40px;
  border: 1px solid var(--c-hairline, var(--color-ink-300));
  border-radius: 7px;
  padding: 8px 12px;
  background: var(--c-card, var(--color-ink-100));
  color: var(--c-ink, var(--color-ink-900));
  font: 600 13px/1.25 var(--c-sans, var(--font-sans));
  cursor: pointer;
}

.studio-action-row > button:hover:not(:disabled) {
  border-color: var(--c-beam, var(--color-beam));
}

.studio-action-row > button:focus-visible {
  outline: 2px solid var(--c-beam, var(--color-beam));
  outline-offset: 2px;
}

.studio-action-row > button:disabled,
.studio-action-row > button[aria-disabled='true'] {
  cursor: not-allowed;
  opacity: 0.55;
}

@media (max-width: 1023px) and (min-width: 641px) {
  .studio-dock {
    width: 320px;
    min-width: 320px;
  }
}

@media (max-width: 640px) {
  .studio-dock {
    position: relative;
    z-index: 60;
    right: auto;
    bottom: auto;
    left: auto;
    width: 100%;
    min-width: 0;
    height: min(38dvh, 320px);
    max-height: calc(100% - var(--studio-work-min-height, 180px));
    flex: none;
    border-top: 1px solid var(--c-hairline, var(--color-ink-200));
    border-left: 0;
    border-radius: var(--c-r-md, var(--radius-panel)) var(--c-r-md, var(--radius-panel)) 0 0;
    box-shadow: 0 -12px 32px rgb(0 0 0 / 24%);
  }

  .studio-dock[data-sheet-state='peek'] {
    height: 96px;
  }

  .studio-dock[data-sheet-state='full'] {
    height: calc(100dvh - var(--studio-composer-height, 72px));
    max-height: calc(100dvh - var(--studio-composer-height, 72px));
  }

  .studio-dock--pane {
    height: 100%;
    max-height: none;
    flex: 1;
    border-top: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .studio-dock__header {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .studio-dock__sheet-controls {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    padding: 2px;
    border: 1px solid var(--c-hairline, var(--color-ink-300));
    border-radius: 7px;
    background: var(--c-card, var(--color-ink-100));
  }

  .studio-dock__sheet-controls button {
    min-height: 44px;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--c-ink-2, var(--color-ink-500));
    font: 600 11px/1 var(--c-sans, var(--font-sans));
  }

  .studio-dock__sheet-controls button[aria-pressed='true'] {
    background: color-mix(in srgb, var(--c-beam, var(--color-beam)) 13%, transparent);
    color: var(--c-ink, var(--color-ink-900));
  }
}

@media (prefers-reduced-motion: reduce) {
  .studio-dock__chevron {
    transition: none;
  }
}
/* ==========================================================================
   The comments sidecar, in the studio's own vocabulary.

   WHY THIS FILE EXISTS AT ALL

   `CommentLayer` was written for the app shell and drew itself in Tailwind's
   tokens — `.panel` (which is `background: var(--color-ink-050)` plus an
   `ink-200` border), `text-ink-900`, and the shared `Button`/`TextArea` from
   `editor/controls`, which are blue-grey rounded form controls. Mounted as a
   full-screen door that was survivable, because the door covered everything
   and there was nothing beside it to disagree with.

   It is a sidecar now. `bench.css` already paints `.benchside` with `--paper`
   precisely so it reads as a sheet laid on the bench — and the panel painted a
   near-white rectangle straight over that paper, with rounded blue-grey inputs,
   against warm paper and graphite chrome. Two design systems, four inches apart.

   `bench.css` and `Bench.tsx` belong to another pass, so the vocabulary is
   borrowed rather than extended: every value below is a token that file already
   declares, or a shape it already draws (`.decide textarea`, `.classbtn`,
   `.eyebrow3`). One chassis, studio-specific cargo — this is the bench's panel
   shape carrying comments, not a new shape.

   Every `var()` carries a literal fallback. The tokens are scoped to
   `.bench-page` and this panel is only ever mounted inside it, but a component
   that renders unreadable when someone mounts it somewhere else is a trap
   waiting for the next person.

   CONTRAST, MEASURED ON --paper #FBF8F2

     --p-ink    #211D15   15.83:1   body and headings
     --p-ink-2  #6B6455    5.54:1   secondary prose
     --p-meta   #6E6656    5.36:1   eyebrows and meta
     --flag     #D6006E    4.85:1   errors, stale remarks
     --beam     #0B756F    5.23:1   the focus ring, and confirmed
     paper on --p-ink     15.83:1   the primary button

   All clear AA for text at every size used here. B's #9A927F (2.92:1) and
   #847E92 (3.68:1) appear nowhere in this file, which is why the roles they
   used to fill are carried by --p-meta and --p-ink-2 instead.
   ========================================================================== */

.cl {
  /* No ground of its own. `.benchside` is already paper, and a second opaque
     fill over it is exactly how this came to read as a bolted-on application. */
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--p-ink, #211D15);
  font-family: var(--sans, 'Avenir Next', system-ui, sans-serif);
}

/* Comments are frequently handled on a phone. Their compact visual labels sit
   inside full touch targets rather than making Reply/Resolve precision taps. */
.cl button {
  min-height: 44px;
}

/* Inside the shared inspector, inherit its real theme rather than the legacy
   warm-paper assumptions. The dock owns the outer padding and chrome. */
.studio-dock .cl {
  --p-ink: var(--c-ink, var(--color-ink-900));
  --p-ink-2: var(--c-ink-2, var(--color-ink-600));
  --p-meta: var(--c-meta, var(--color-ink-400));
  --p-hairline: var(--c-hairline, var(--color-ink-200));
  --paper: var(--c-paper, var(--color-ink-050));
}

.studio-dock .cl-dock .cl-body {
  padding: 0;
}

.studio-dock .cl-dock .cl-foot {
  padding: 12px 0 0;
}

.studio-dock .cl-dock .cl-write {
  background: var(--c-card, var(--color-ink-100));
  color: var(--c-ink, var(--color-ink-900));
}

/* --- the eyebrow idiom, which the Close button already spoke ------------- */
.cl-eyebrow {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 9px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--p-meta, #6E6656);
}

.cl-head {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
}

.cl-title {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--p-ink, #211D15);
}

.cl-close {
  margin-left: auto;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 9px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--p-meta, #6E6656);
  background: none;
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 7px;
  padding: 5px 9px;
  cursor: pointer;
}
.cl-close:hover {
  color: var(--p-ink, #211D15);
  border-color: rgba(33, 29, 21, 0.3);
}

/* --- the scroll --------------------------------------------------------- */
.cl-body {
  min-height: 0;
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
}

.cl-quiet {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--p-ink-2, #6B6455);
}

.cl-error {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--flag, #D6006E);
}

/* A group's frame label. A button when it can move the deck, and it stops
   looking pressable when it cannot rather than going grey and staying so. */
.cl-group {
  margin-top: 14px;
}
.cl-group:first-child {
  margin-top: 0;
}
.cl-grouplabel {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.cl-grouplabel:disabled {
  cursor: default;
}
.cl-grouplabel:hover:enabled {
  color: var(--p-ink, #211D15);
}

.cl-list {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
.cl-list > li + li {
  margin-top: 8px;
}

/* --- a remark, and a sign-off: the same card ---------------------------- */
.cl-card {
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 9px;
  padding: 10px 11px;
  background: rgba(255, 255, 255, 0.45);
}
.cl-card.spent {
  opacity: 0.6;
}
.cl-card.cleared {
  border-color: var(--beam, #0B756F);
}
.cl-card.waiting {
  border-color: rgba(33, 29, 21, 0.34);
}

.cl-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
}
.cl-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--p-ink, #211D15);
}
.cl-when {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--p-meta, #6E6656);
}

/* Who wrote it. Outside, or one of ours — the distinction the panel exists
   to keep, so it is a mark rather than a colour wash. */
.cl-from {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 4px;
  padding: 2px 5px;
  color: var(--p-meta, #6E6656);
}
.cl-from.outside {
  color: var(--beam, #0B756F);
  border-color: var(--beam, #0B756F);
}

.cl-body-text {
  margin: 6px 0 0;
  white-space: pre-wrap;
  font-size: 13px;
  line-height: 1.6;
  color: var(--p-ink, #211D15);
}

.cl-note {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--p-ink-2, #6B6455);
}
.cl-note.flagged {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--flag, #D6006E);
}

.cl-rule {
  margin: 16px 0;
  border: 0;
  border-top: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
}

.cl-fold {
  margin-top: 16px;
}
.cl-fold > summary {
  cursor: pointer;
}
.cl-fold > summary:hover {
  color: var(--p-ink, #211D15);
}

/* --- the composer, which is `.decide` turned over onto the paper side --- */
.cl-foot {
  flex: none;
  border-top: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  padding: 12px 16px 14px;
}

.cl-write {
  width: 100%;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 7px;
  color: var(--p-ink, #211D15);
  font-family: var(--sans, 'Avenir Next', system-ui, sans-serif);
  font-size: 12.5px;
  line-height: 1.5;
  padding: 8px 10px;
  min-height: 56px;
  resize: vertical;
  outline: none;
}
.cl-write::placeholder {
  color: var(--p-meta, #6E6656);
}
/* The bench's own focus answer — `.decide textarea:focus` moves the border
   rather than adding a ring, so this does too. 5.23:1 against paper. */
.cl-write:focus {
  border-color: var(--beam, #0B756F);
}

.cl-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
}

/* `.classbtn`'s shape. Selected is a fill rather than a heavier border,
   because two bordered pills side by side ask which one is chosen. */
.cl-scope {
  font-size: 11.5px;
  color: var(--p-ink-2, #6B6455);
  background: none;
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 7px;
  padding: 6px 10px;
  cursor: pointer;
}
.cl-scope:hover:enabled {
  color: var(--p-ink, #211D15);
}
.cl-scope[aria-pressed='true'] {
  color: var(--p-ink, #211D15);
  background: rgba(33, 29, 21, 0.07);
  border-color: rgba(33, 29, 21, 0.3);
}
.cl-scope:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.cl-post {
  margin-left: auto;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--paper, #FBF8F2);
  background: var(--p-ink, #211D15);
  border: 1px solid var(--p-ink, #211D15);
  border-radius: 7px;
  padding: 6px 12px;
  cursor: pointer;
}
.cl-post:hover:enabled {
  background: var(--p-ink-2, #6B6455);
  border-color: var(--p-ink-2, #6B6455);
}
.cl-post:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.cl-confirm {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--paper, #FBF8F2);
  background: var(--p-ink, #211D15);
  border: 1px solid var(--p-ink, #211D15);
  border-radius: 7px;
  padding: 6px 12px;
  cursor: pointer;
}
.cl-confirm:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.cl-small {
  font-size: 11.5px;
  color: var(--p-ink-2, #6B6455);
  background: none;
  border: 1px solid var(--p-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 7px;
  padding: 5px 9px;
  cursor: pointer;
}
.cl-small:hover:enabled {
  color: var(--p-ink, #211D15);
}
.cl-small:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.cl-hint {
  margin: 8px 0 0;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--p-ink-2, #6B6455);
}

.cl-anchor-draft,
.cl-anchor-state {
  border-left: 2px solid var(--beam, #0B756F);
  padding-left: 8px;
}

.cl-anchor-state.moved,
.cl-anchor-state.stale,
.cl-anchor-state.gone {
  border-left-color: var(--pink, #FF3F91);
}

.cl-show-all { margin-bottom: 12px; }

.cl :focus-visible {
  outline: 2px solid var(--beam, #0B756F);
  outline-offset: 2px;
}
.studio-composer-stack {
  display: grid;
  width: 100%;
  min-width: 0;
}

.studio-composer {
  display: flex;
  width: 100%;
  min-height: 58px;
  align-items: flex-end;
  gap: 12px;
  box-sizing: border-box;
  padding: 8px 9px 8px 17px;
  border: 1px solid var(--line-strong, var(--c-frame-line, #4a4556));
  border-radius: var(--radius-panel, var(--c-r-card, 10px));
  background: var(--surface, var(--c-frame-2, #37333f));
  box-shadow: none;
  color: var(--ink, var(--c-readout-hi, #f4f2f8));
}

.studio-composer:focus-within {
  border-color: var(--c-beam-frame, #22e0d5);
}

.studio-composer:has(textarea:focus-visible) {
  outline: 2px solid var(--c-beam-frame, #22e0d5);
  outline-offset: 2px;
}

.studio-composer__target {
  display: inline-flex;
  min-width: 0;
  max-width: min(40%, 360px);
  flex: none;
  align-items: center;
  gap: 6px;
  padding: 5px 7px 5px 9px;
  border: 1px solid color-mix(in srgb, var(--c-beam-frame, #22e0d5) 32%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-beam, #0b756f) 18%, transparent);
  color: var(--c-readout, #beb8ca);
  font: 400 11px/1.2 var(--c-sans, 'Avenir Next', system-ui, sans-serif);
}

/* A studio rail is narrow even on a wide screen. Selection context must not
   compete with the writing field for that one row: it owns a row, then the
   attachment / field / shortcut / send controls keep the row below. */
.studio-composer:has(.studio-composer__target) {
  flex-wrap: wrap;
}

.studio-composer:has(.studio-composer__target) .studio-composer__target {
  flex-basis: 100%;
  max-width: 100%;
  order: -1;
}

.studio-composer__target-label {
  flex: none;
  color: var(--c-readout-hi, #f4f2f8);
}

.studio-composer__target-excerpt {
  overflow: hidden;
  min-width: 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.studio-composer__target-clear {
  display: grid;
  width: 18px;
  height: 18px;
  flex: none;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.studio-composer__target-clear:hover,
.studio-composer__target-clear:focus-visible {
  background: color-mix(in srgb, var(--c-readout-hi, #f4f2f8) 12%, transparent);
  color: var(--c-readout-hi, #f4f2f8);
  outline: none;
}

.studio-composer textarea {
  max-height: 112px;
  min-width: 0;
  flex: 1;
  resize: none;
  overflow-y: auto;
  border: 0;
  outline: 0 !important;
  background: transparent;
  color: inherit;
  font: 400 15px/1.4 var(--c-sans, 'Avenir Next', system-ui, sans-serif);
}

/* The composer owns the focus treatment as one compound control. Global field
   focus rules must not draw a second ring inside the pill. */
.studio-composer textarea:focus-visible {
  outline: none !important;
  box-shadow: none !important;
}

.studio-composer textarea::placeholder {
  color: var(--c-readout, #beb8ca);
}

.studio-composer__shortcut {
  flex: none;
  color: var(--c-readout);
  font: 400 10px/1 var(--c-mono, ui-monospace, monospace);
}

.studio-composer__busy {
  display: grid;
  width: 18px;
  height: 18px;
  flex: none;
  place-items: center;
}

.studio-composer__busy > span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-beam-frame, #22e0d5);
  animation: studio-composer-pulse 1.1s ease-in-out infinite;
}

/* The visible control itself is the target. A 36px arrow inside an invisible
   44px hit extension left both Copy and Carousel looking and feeling too small
   in the browser, especially beside a wrapped contextual prompt. */
.studio-composer__send {
  position: relative;
  display: grid;
  width: 44px;
  height: 44px;
  flex: none;
  margin: 0;
  place-items: center;
  border: 0;
  border-radius: var(--r-sm, 8px);
  background: var(--beam, var(--c-beam, #0b756f));
  color: var(--on-beam, var(--paper));
  cursor: pointer;
}

.studio-composer__send::before {
  position: absolute;
  inset: 0;
  content: '';
}

.studio-composer__send:hover:not(:disabled):not([aria-disabled='true']) {
  background: color-mix(in srgb, var(--c-beam, #0b756f) 82%, white);
}

/* The send control on an empty composer, or on a refused one.

   Opacity faded the arrow and its ground together; a flat unavailable ground
   keeps the affordance readable so the person can see what it will do once
   there is something to send.

   THE GROUND IS A TOKEN AND NOT A LITERAL. It was `#3a3648` on `#9b95ab`,
   picked against the graphite composer this file was written for, and Copy
   Studio's composer follows the theme now: in light that drew a near-black
   pill in the middle of a white plate. `--surface-3` is the board's own
   unavailable ground — `pitch.css:741` gives it to `.cta.off` — and `--ink-3`
   is real ink on it: the arrow measures 5.34:1 light and 6.67:1 dark, at
   `opacity: 1`.

   AND IT KEEPS ITS SHAPE. The bar this disc sits in is `--c-frame-2`, which
   resolves to `--surface-3` here, so the ground alone measured 1.00:1 against
   it — a control with no boundary, which is the same defect from the other
   end. `.cta.off` carries a `--line` edge for exactly this reason; on a
   ground that IS `--surface-3` the edge has to be `--line-control`
   (`ds.css:905-911`, the token whose lightness was set to clear 3:1 on every
   ground a control sits on). Measured ON THIS DISC, against the bar behind
   it: 3.11:1 light, 3.10:1 dark. (3.41 / 3.26 is the same token on the
   sign-off panel's quiet box, a different ground; the two pairs were
   transposed when this was written.)

   Not `--c-beam`: the act's colour on a control that will not act is the
   thing this rule exists to stop. The fallbacks are mock.css's light values,
   and they are here only until the Bench's root carries `.mockroot` (P6-a). */
.studio-composer__send:disabled,
.studio-composer__send[aria-disabled='true'] {
  cursor: default;
  opacity: 1;
  background: var(--surface-3, #f0eff3);
  border: 1px solid var(--line-control, #8b84a0);
  color: var(--ink-3, #655f73);
}

/* The refusal, once, under the pill it belongs to. Prose in the readout voice
   rather than an alert: the seat has not changed under anybody's feet, it was
   always this way, and a red box for a standing condition is noise. */
.studio-composer__refusal {
  margin: 8px 0 0;
  padding: 0 17px;
  color: var(--c-readout, #beb8ca);
  font: 400 12px/1.5 var(--c-sans, 'Avenir Next', system-ui, sans-serif);
}

.studio-composer__status {
  min-width: 0;
  padding: 8px 4px 0;
  color: var(--ink-3, var(--c-readout, #beb8ca));
  font: 400 12px/1.5 var(--sans, var(--c-sans, system-ui, sans-serif));
}

.studio-composer__send:focus-visible {
  outline: 2px solid var(--c-beam-frame, #22e0d5);
  outline-offset: 2px;
}

@keyframes studio-composer-pulse {
  0%, 100% { opacity: 0.35; transform: scale(0.75); }
  50% { opacity: 1; transform: scale(1); }
}

@media (max-width: 640px) {
  .studio-composer {
    min-height: 54px;
    padding-left: 14px;
  }

  .studio-composer__shortcut {
    display: none;
  }

  .studio-composer__target {
    max-width: 45%;
  }

  /* Selection context is useful, but it cannot take the writing field's row.
     Give it the full first row and keep the field and send below it. */
  .studio-composer:has(.studio-composer__target) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .studio-composer:has(.studio-composer__target) .studio-composer__target {
    grid-column: 1 / -1;
    max-width: 100%;
  }

  .studio-composer:has(.studio-composer__target) textarea {
    grid-column: 1;
  }

  .studio-composer:has(.studio-composer__target) .studio-composer__send {
    grid-column: 2;
  }
}

@media (prefers-reduced-motion: reduce) {
  .studio-composer__busy > span {
    animation: none;
    opacity: 1;
  }
}
.studio-shell {
  display: grid;
  width: 100%;
  min-width: 0;
  min-height: 0;
  height: 100%;
  grid-template-rows: minmax(0, 1fr);
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
}

.studio-shell__tools,
.studio-shell__assistant,
.studio-shell__artifact,
.studio-shell__dock {
  min-width: 0;
  min-height: 0;
  overflow: auto;
}

.studio-shell__tools {
  grid-column: 1;
  border-right: 1px solid var(--frame-line, var(--line));
  background: var(--frame, var(--surface-2));
}

.studio-shell__assistant {
  grid-column: 2;
  border-right: 1px solid var(--line);
  background: var(--surface);
}

.studio-shell__artifact {
  grid-column: 3;
  background: var(--surface-2);
}

.studio-shell__dock {
  grid-column: 4;
  border-left: 1px solid var(--line);
  background: var(--surface);
}

.studio-shell__pane-switcher {
  display: none;
}

@media (min-width: 768px) and (max-width: 1023px) {
  .studio-shell__assistant,
  .studio-shell__dock {
    grid-column: 2;
  }

  .studio-shell__artifact {
    grid-column: 3;
  }

}

@media (max-width: 767px) {
  .studio-shell {
    grid-template-rows: minmax(0, 1fr) auto;
  }

  .studio-shell__tools {
    display: none;
  }

  .studio-shell__assistant,
  .studio-shell__artifact,
  .studio-shell__dock {
    grid-row: 1;
    grid-column: 1;
    border: 0;
  }

  .studio-shell__pane-switcher {
    display: grid;
    grid-row: 2;
    grid-column: 1;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    gap: 1px;
    padding: 4px;
    border-top: 1px solid var(--line);
    background: var(--surface);
  }

  .studio-shell__pane-switcher button {
    min-height: 44px;
    border: 0;
    border-radius: var(--r-sm, 6px);
    background: transparent;
    color: var(--ink-3);
    font: 600 12px/1 var(--sans, var(--font-sans));
  }

  .studio-shell__pane-switcher button[aria-pressed='true'] {
    background: var(--surface-3);
    color: var(--ink);
  }

  .studio-shell__pane-switcher button:focus-visible {
    outline: 2px solid var(--beam, var(--color-beam));
    outline-offset: -2px;
  }
}
/*
 * THE ASSISTANT PANEL, LIFTED FROM THE FINAL DESIGN.
 *
 * Source, transcribed rather than interpreted:
 *   docs/claude-code/production-recovery-2026-08-26/designs/final-activity-ledger.html
 *
 * Every rule below is that file's, with two mechanical changes and no others:
 * each selector is scoped under `.inkstand-assistant` so it cannot collide with
 * the existing Studio stylesheets, which are untouched; and the mockup's own
 * chrome — the page intro, the fake rail, the canvas, the principle cards — is
 * dropped, because it is the page the design was presented ON and not the panel
 * it specifies.
 *
 * The design's palette is declared here as the panel's own ground rather than
 * inherited, because that is what the design draws: a dark instrument panel
 * beside the artwork, in both themes. The artwork carries the theme; the
 * instrument does not.
 *
 * DO NOT tidy these values toward the surrounding codebase. They are the
 * authority. A metric that disagrees with the design is a defect in this file.
 */

.inkstand-assistant {
  --panel: #211e29;
  --rail: #131118;
  --line: #3b3645;
  --muted: #958e9f;
  --text: #f4f1f6;
  --violet: #a989ff;
  --green: #79d3a6;
  --orange: #e6b46e;

  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  height: 100%;
  background: var(--panel);
  color: var(--text);
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}

.inkstand-assistant .panel { background:var(--panel);border-right:1px solid var(--line);display:flex;flex-direction:column;min-width:0 }
.inkstand-assistant .head { height:50px;padding:0 15px;display:flex;align-items:center;border-bottom:1px solid var(--line);font-size:13px;font-weight:700 }
.inkstand-assistant .head span { margin-left:auto;color:var(--muted);font-size:17px;font-weight:400 }
.inkstand-assistant .scope { padding:11px 15px;display:grid;grid-template-columns:20px 1fr auto;gap:8px;align-items:center }
.inkstand-assistant .scope-icon { font:700 15px Georgia }
.inkstand-assistant .scope-copy { min-width:0 }
.inkstand-assistant .scope-copy strong { display:block;font-size:10px }
.inkstand-assistant .scope-copy p { margin:2px 0 0;color:#9f98a7;font-size:9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.inkstand-assistant .scope-frame { color:#81798d;font:9px ui-monospace }
.inkstand-assistant .command-wrap { padding:0 13px 14px;border-bottom:1px solid var(--line) }
.inkstand-assistant .command { border:1px solid #625a72;background:#18161e;border-radius:10px;min-height:43px;padding:10px 40px 10px 11px;color:#9992a1;font-size:10px;position:relative;display:flex;align-items:center }
.inkstand-assistant .send { position:absolute;right:7px;width:27px;height:27px;border-radius:7px;background:var(--violet);color:#16131c;display:grid;place-items:center;font-weight:800 }
.inkstand-assistant .activity-head { display:flex;align-items:center;padding:14px 16px 8px }
.inkstand-assistant .activity-head strong { font-size:10px;text-transform:uppercase;letter-spacing:.12em;color:#a49dab }
.inkstand-assistant .activity-head span { margin-left:auto;color:#777080;font-size:9px }
.inkstand-assistant .timeline { flex:1;min-height:0;overflow:auto;padding:2px 14px 20px 27px;position:relative }
.inkstand-assistant .timeline:before { content:"";position:absolute;left:20px;top:13px;bottom:26px;width:1px;background:#494352 }
.inkstand-assistant .event { position:relative;padding:10px 4px 14px 13px;border-bottom:1px solid #37323f }
.inkstand-assistant .node { position:absolute;left:-12px;top:15px;width:9px;height:9px;border-radius:50%;background:#8b8297;border:3px solid var(--panel) }
.inkstand-assistant .event.latest .node { background:var(--green) }
.inkstand-assistant .event.undone .node { background:transparent;border:2px solid #92899e }
.inkstand-assistant .event-top { display:flex;gap:8px;align-items:baseline }
.inkstand-assistant .event-title { font-size:11px;font-weight:700 }
.inkstand-assistant .event-time { margin-left:auto;color:#777080;font:8px ui-monospace }
.inkstand-assistant .event-meta { font-size:9px;color:#918a9a;margin-top:3px }
.inkstand-assistant .event-summary { font-size:9px;color:#bbb4c1;margin-top:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis }
.inkstand-assistant .event-actions { display:flex;gap:10px;margin-top:8px }
.inkstand-assistant .event-actions button { border:0;background:transparent;color:#cfc8d5;padding:0;font:700 9px Inter,system-ui;cursor:pointer }
.inkstand-assistant .event-actions button.primary { color:#eee9f7 }
.inkstand-assistant .event-actions button.muted { color:#88808f }
.inkstand-assistant .detail { display:none;margin-top:9px;padding:9px 10px;background:#1a1820;border-left:2px solid #665e72;font-size:9px;line-height:1.4;color:#bdb6c4 }
.inkstand-assistant .detail.show { display:block }
.inkstand-assistant .detail small { display:block;color:#7f7789;text-transform:uppercase;letter-spacing:.1em;margin-bottom:2px }
.inkstand-assistant .detail .after { margin-top:7px }
.inkstand-assistant .manual { color:#b4adc0 }
.inkstand-assistant .assistant-mark { color:var(--violet) }

/* The clarification, `.question` in the design: a rule down the left, sitting
   under the composer. Temporary — it is a request for one more word, not an
   entry in the history, and it never becomes one. */
.inkstand-assistant .question { margin-top:11px;border-left:3px solid #8061c9;padding:8px 11px;font-size:11px }

/* A failure takes the same block in a colour that reads as stopped. The design
   draws one temporary region under the composer and not two, so this is that
   region wearing a different edge rather than a second thing on the screen. */
.inkstand-assistant .question.failed { border-left-color: var(--orange); }

/* Keeps the timeline scrolling under a pinned head, scope and composer. The
   design is a fixed-height mockup and never says what happens at 40 events;
   the panel is a column and this is the only part of it that grows. */
.inkstand-assistant .timeline { overflow-y: auto; flex: 1; min-height: 0; }
.inkstand-assistant .empty { color: var(--muted); font-size: 11px; padding: 14px 0; }

/* The design draws `.command` AS the input — a bordered box with the prompt
   text inside it and the send button pinned right. A real textarea therefore
   has to disappear into it completely and inherit its type, rather than bring
   a second border and a second font. */
.inkstand-assistant .command { align-items: flex-end; }
.inkstand-assistant .command textarea {
  flex: 1; min-width: 0; border: 0; outline: 0; resize: none; background: transparent;
  color: var(--text); font: inherit; line-height: 1.45; padding: 0; margin: 0;
  min-height: 23px; max-height: 132px; field-sizing: content;
}
.inkstand-assistant .command textarea::placeholder { color: #9992a1; }
.inkstand-assistant .command:focus-within { border-color: var(--violet); }
/* Bottom-anchored, as the contextual design pins it (`.send { bottom:9px }`),
   so the arrow stays with the last line as the box grows. */
.inkstand-assistant .send { bottom: 8px; border: 0; cursor: pointer; }
.inkstand-assistant .send:disabled { opacity: .45; cursor: default; }
.inkstand-assistant .event-actions button:focus-visible,
.inkstand-assistant .send:focus-visible,
.inkstand-assistant .head span:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

/* The resize seam. The design's own hairline (`--line`) widened to something a
   pointer can actually hit, and it takes the full height of the panel's right
   edge because that is where the boundary is. */
.inkstand-assistant { position: relative; }
.inkstand-assistant .seam {
  position: absolute; top: 0; right: -4px; bottom: 0; width: 9px;
  cursor: col-resize; background: transparent; touch-action: none;
}
.inkstand-assistant .seam:hover, .inkstand-assistant .seam:focus-visible {
  background: linear-gradient(to right, transparent 3px, var(--violet) 3px, var(--violet) 5px, transparent 5px);
  outline: none;
}

/* The head's minimize control takes the `×` treatment the design gives the
   span it drew there, with the button chrome removed. */
.inkstand-assistant .head .close {
  margin-left: auto; color: var(--muted); font-size: 17px; font-weight: 400;
  border: 0; background: transparent; cursor: pointer; line-height: 1; padding: 0;
}

/* The timeline is a `ul`; the design drew rows of divs and specifies the
   padding, so only the list chrome is removed. */
.inkstand-assistant .timeline { list-style: none; margin: 0; }

/* A consequence takes the summary's treatment in the design's warning colour,
   and wraps — this is the one line on a row that must not be truncated, because
   half of "now stops a release" is worse than none of it. */
.inkstand-assistant .event-consequence {
  font-size: 9px; color: var(--orange); margin-top: 5px; white-space: normal;
}

/*
 * INTERACTION GEOMETRY IS LARGER THAN THE GLYPH.
 *
 * The design draws a small `×` and small text actions, and it is right to —
 * this is a dense instrument panel and 44px buttons would wreck its rhythm.
 * But a 9px word is a 9px target, and this repo's own standard is that every
 * pointer and touch target clears 44×44 while the chrome stays visually
 * compact. So the box keeps its drawn size and the TARGET is expanded past it,
 * which changes nothing on screen.
 *
 * The deleted rail carried this for its minimize control in `bench.css`, keyed
 * to a class that no longer exists — so the control lost its target silently
 * when the class went.
 */
.inkstand-assistant .head .close { min-width: 44px; min-height: 44px; margin-right: -13px; }
.inkstand-assistant .event-actions button,
.inkstand-assistant .question .event-actions button { position: relative; }
.inkstand-assistant .event-actions button::after {
  content: ""; position: absolute; left: -6px; right: -6px; top: 50%;
  transform: translateY(-50%); height: 44px;
}
/* The direction card wears the receipt's own tokens (see studioReceipt.css)
   because it lives in the same transcript slot: one panel idiom for the
   assistant's structured cargo. The chips inside are `.studio-choice`, styled
   by studioDock.css. */

.design-direction {
  display: grid;
  gap: 12px;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  margin: 0 0 8px;
  padding: 12px 14px;
  border: 1px solid var(--line-strong, var(--c-frame-line, #4a4556));
  border-radius: var(--radius-panel, var(--c-r-card, 10px));
  background: var(--surface, var(--c-frame-2, #37333f));
  color: var(--ink, var(--c-readout-hi, #f4f2f8));
}

.design-direction__question {
  display: grid;
  gap: 6px;
}

.design-direction__prompt {
  margin: 0;
  font: 600 13px/1.35 var(--sans, var(--c-sans, system-ui));
  color: inherit;
}

.design-direction__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.design-direction__action {
  min-height: 44px;
  min-width: 44px;
  padding: 0 14px;
  border: 1px solid var(--line-strong, var(--c-frame-line, #4a4556));
  border-radius: var(--radius-panel, var(--c-r-card, 10px));
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.design-direction__action:hover:not(:disabled) {
  border-color: var(--c-beam-frame, #22e0d5);
}

.design-direction__action:focus-visible {
  outline: 2px solid var(--c-beam-frame, #22e0d5);
  outline-offset: 2px;
}

.design-direction__action:disabled {
  cursor: default;
  opacity: 0.55;
}

.design-direction__action--quiet {
  border-color: transparent;
  color: var(--c-readout-dim, #9f9aab);
}
/*
 * THE CONSOLE ON THE BENCH'S FASCIA.
 *
 * ---------------------------------------------------------------------------
 * WHAT IS HERE AND WHAT DELIBERATELY IS NOT
 * ---------------------------------------------------------------------------
 *
 * The pill itself is NOT drawn here. It is `.c-capsule` in `calm.css` — the
 * shape that stylesheet owns and that the rack's filter already wears — and
 * drawing a third one would repeat exactly the mistake this whole change
 * exists to stop: `.c-seltool` is owned by `calm.css`, Copy Studio wears a
 * byte-duplicate of it in `instrument.css`, and the two have already drifted.
 *
 * So this file holds only what is about the BENCH: where the bar sits in the
 * column, and the transcript that rides above the pill.
 *
 * ---------------------------------------------------------------------------
 * NOTHING PERMANENT JOINS THE BENCH
 * ---------------------------------------------------------------------------
 *
 * `Bench.tsx`'s own rule is that a new feature is a verb on the capsule, a row
 * in the spine, or a door in the menu — nothing may add permanent furniture.
 * The pill is the exception the console spec settles, and it earns it by being
 * the surface rather than a control on it. The transcript keeps the rule: it
 * exists only while there is something to say, and it is gone again when the
 * reader hides it. A deck is looked at, and a panel that is always there is a
 * panel that is always in the way.
 */

.bconsole {
  /*
   * THE STRIP'S GROUND, because this is the same fascia — and the strip is the
   * board's `.cv-strip` now, which is `--surface-2`. It was `--frame`, a
   * literal graphite, back when the strip and the two plates were graphite
   * too; keeping it would have left one dark band under a page-coloured
   * screen.
   */
  background: var(--surface-2);
  flex: 1;
  min-height: 0;
  display: flex;
  padding: 12px;
  position: relative;
  z-index: 21;
}

.bconsole .bcomposer {
  position: relative;
  width: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

/*
 * THE PILL'S COLOURS, HANDED OVER RATHER THAN REDRAWN.
 *
 * `studio-composer.css` is P6-b's file and it already takes its palette
 * through `--c-*` custom properties with graphite fallbacks — written that way
 * so a studio can state its own ground without a second copy of the shape.
 * So the Bench states one, on tokens, and the pill flips with the page.
 */
.bconsole .studio-composer {
  --c-frame-2: var(--surface);
  --c-frame-line: var(--line-strong);
  --c-readout: var(--ink-3);
  --c-readout-dim: var(--ink-4);
  --c-readout-hi: var(--ink);
  --c-beam: var(--beam);
  --c-beam-frame: var(--beam);
  --c-sans: var(--sans);
  box-shadow: var(--shadow-2);
}

/*
 * THE REFUSAL, UNDER THE CAPSULE, WITH THE ID THE SEND POINTS AT.
 *
 * The node is `console.tsx`'s (the director's 2026-08-21 seam) and the ground
 * it lands on is this studio's, so the type is stated here. Not magenta and
 * not red: a seat is neither a finding nor something going wrong, and the
 * sentence is a fact about who is reading.
 */
.bconsole .studio-composer__refusal {
  margin: 8px 0 0;
  padding: 0 18px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-3);
  text-align: center;
}

/*
 * THE TRANSCRIPT, WHICH PUSHES THE DECK RATHER THAN COVERING IT.
 *
 * Copy Studio's rule is that the console is part of the fascia so it can never
 * cover the words. Drawn as a floating panel over the stage this broke that on
 * the first answer — seen in a browser, not in a test: a paragraph about slide
 * 3 sitting on top of slide 1.
 *
 * In flow instead. `.bconsole` is `flex: none` in the bench column and `.stage`
 * is `flex: 1`, so the bar growing makes the artwork smaller and never hides
 * it. The deck being talked about stays whole and in view, which is the only
 * way to check what the co-reader just said about it.
 */
.bconsole .btranscript {
  margin-bottom: 10px;
  /* Capped so the deck keeps the room. The console is here to talk about the
     artwork, and an answer that leaves a thumbnail to check it against is an
     answer nobody can check. */
  max-height: none;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}

.bconsole .bflow {
  overflow-y: auto;
  padding: 14px 16px 16px;
  min-height: 0;
}

.bconsole .bclose {
  align-self: flex-end;
  flex: none;
  background: none;
  border: 0;
  cursor: pointer;
  /* One word — "Minimize" — on a button. The transcript beside it is the
     co-reader talking about the deck, and nothing in either is an identifier,
     so the console is the UI sans throughout. */
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-3);
  padding: 9px 14px 0;
}
.bconsole .bclose:hover {
  color: var(--ink);
}

.bconsole .breopen {
  display: block;
  margin: 0 0 8px auto;
  border: 0;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  font-family: var(--sans);
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.bconsole .breopen:hover {
  color: var(--ink);
}

.bconsole .bench-design-deck {
  align-self: flex-start;
  margin: 0 0 8px;
  color: var(--ink-3);
  font: 12px/1.4 var(--sans);
}
.bconsole .bench-design-deck > div {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.bconsole .bench-design-deck button {
  min-height: 36px;
  padding: 7px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font: 600 12px/1 var(--sans);
}
.bconsole .bench-design-deck button:hover {
  background: var(--surface-3);
}

/*
 * THE TURNS COME FROM THE SHARED CHASSIS, which is written in the app shell's
 * ink scale — a scale that inverts with the theme. This panel used to be paper
 * whatever the theme was, so every one of these rules restated a literal
 * against that paper. The panel is `--surface` now, which IS the app's own
 * ground, so the restatements are token pairs and the panel cannot come out
 * dark-on-dark in either theme.
 */
.bconsole .bflow p,
.bconsole .bflow li,
.bconsole .bflow summary {
  color: var(--ink-2);
}
.bconsole .bflow .text-ink-900,
.bconsole .bflow strong {
  color: var(--ink);
}
.bconsole .bflow .rounded-2xl {
  background: var(--surface-3);
  border-color: var(--line);
  color: var(--ink);
}
.bconsole .bflow .rounded-lg {
  background: var(--surface-2);
  border-color: var(--line);
}
.bconsole .bflow .rounded-lg p {
  /* A proposal is the deck's own words, so it keeps the serif the artwork and
     the finding notes give them. */
  color: var(--ink);
  white-space: pre-line;
}

/* A generated deck can contain many frames. Keep the preview useful without
   letting it turn the conversation into a second canvas. */
.bconsole .bflow .rounded-lg > p:first-child {
  max-height: 84px;
  overflow-y: auto;
  padding-right: 6px;
}
.bconsole .bflow .rounded-lg > p.tech {
  max-height: 58px;
  overflow-y: auto;
}
.bconsole .bflow button {
  color: var(--ink);
  border-color: var(--line-strong);
  background: transparent;
}

/*
 * THE ONE THAT TAKES THE PROPOSAL.
 *
 * `Button variant="primary"` paints `bg-ink-900 text-ink-000` — the app's own
 * inverting pair — and this panel used to be paper regardless of the theme, so
 * on the bench it resolved to near-black on near-black and the words "Use
 * this" were an unreadable block. Seen in a browser, on the first card the
 * console ever offered.
 *
 * The panel is on the page's own surface now, so the pair inverts WITH its
 * ground and the reason for a literal is gone. What is stated here is only the
 * board's own primary — `pitch.css`'s `.cta` is `--ink` on `--paper` — so the
 * one control that acts inside this panel matches every other primary on the
 * screen.
 *
 * The utility class is the selector because it is the literal one
 * `controls.tsx` emits for that variant, and a shared control should not grow
 * a prop for one surface's ground.
 */
.bconsole .bflow button[class*='bg-ink-900'] {
  background: var(--ink);
  color: var(--paper);
  border: 0;
}
.bconsole .bflow button[class*='bg-ink-900']:hover:not(:disabled) {
  background: var(--ink-2);
}
/* ==========================================================================
   REVIEW & RELEASE — the dedicated mode
   ==========================================================================
   Larger than the 360px dock it replaces and deliberately smaller than the
   window: the Studio stays visible and inert behind the scrim, because the
   thing being released is on it and a person has to be able to see that they
   are standing in front of their own work rather than in a new room.

   Tokens only, and `calm.css`'s `--c-*` set, which is the one both Studios
   load. Fallbacks are the same values `calm.css` declares, so the mode still
   paints if it is mounted somewhere that stylesheet has not reached.
   ========================================================================== */

.rr-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(12, 10, 16, 0.62);
}

.rr {
  display: flex;
  flex-direction: column;
  width: 84%;
  max-width: 1180px;
  min-width: 0;
  height: 86%;
  max-height: 900px;
  overflow: hidden;
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 12px;
  background: var(--c-paper, #fbf8f2);
  color: var(--c-ink, #211d15);
  box-shadow: var(--c-e-menu, 0 3px 8px rgba(23, 21, 28, 0.08), 0 14px 40px rgba(23, 21, 28, 0.18));
}

.rr__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 16px 20px 14px;
  border-bottom: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
}

.rr__title {
  margin: 0;
  font: 600 var(--c-ui-title, 23px) / 1.15 var(--c-sans, system-ui, sans-serif);
  letter-spacing: -0.01em;
}

.rr__subject {
  margin: 4px 0 0;
  font: 400 var(--c-ui, 13.5px) / 1.4 var(--c-sans, system-ui, sans-serif);
  color: var(--c-meta, #767061);
}

.rr__close,
.rr__act {
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: var(--c-r, 9px);
  padding: 7px 12px;
  background: transparent;
  color: inherit;
  font: 500 var(--c-ui, 13.5px) / 1 var(--c-sans, system-ui, sans-serif);
  cursor: pointer;
}

.rr__act {
  margin-top: 18px;
  background: var(--c-ink, #211d15);
  border-color: var(--c-ink, #211d15);
  color: var(--c-paper, #fbf8f2);
}

.rr__act[aria-disabled='true'] {
  cursor: not-allowed;
  opacity: 0.5;
}

.rr__body {
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr) 268px;
  min-height: 0;
  flex: 1;
}

.rr__steps,
.rr__stage,
.rr__bound {
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 20px;
}

.rr__steps {
  border-right: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
}

.rr__steps ol {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rr-step > button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  border-radius: var(--c-r-sm, 6px);
  padding: 8px 9px;
  background: transparent;
  color: inherit;
  font: 500 var(--c-ui, 13.5px) / 1 var(--c-sans, system-ui, sans-serif);
  text-align: left;
  cursor: pointer;
}

.rr-step > button[aria-current='step'] {
  background: var(--c-note-bg, #f4f2f6);
}

.rr-step > button[aria-disabled='true'] {
  cursor: not-allowed;
  color: var(--c-meta, #767061);
}

.rr-step__ord {
  flex: none;
  width: 18px;
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-gov-sm, 9.5px);
  color: var(--c-meta, #767061);
}

.rr-step__label { flex: 1; }

.rr-step__state {
  flex: none;
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-gov-sm, 9.5px);
  letter-spacing: var(--c-gov-track, 0.13em);
  text-transform: uppercase;
  color: var(--c-meta, #767061);
}

.rr-step--satisfied .rr-step__state { color: var(--c-beam, #0b756f); }

.rr-step__note {
  margin: 2px 0 8px 27px;
  font: 400 var(--c-ui-sm, 12px) / 1.45 var(--c-sans, system-ui, sans-serif);
  color: var(--c-meta, #767061);
}

.rr__stage-title {
  margin: 0 0 12px;
  font: 600 var(--c-ui-lg, 14.5px) / 1.2 var(--c-sans, system-ui, sans-serif);
}

.rr__alert,
.rr__refusal {
  margin: 0 0 12px;
  font: 400 var(--c-ui, 13.5px) / 1.5 var(--c-sans, system-ui, sans-serif);
  color: var(--c-meta, #767061);
}

.rr-preview__frame {
  margin: 0;
  display: grid;
  justify-items: center;
  gap: 8px;
}

/* THE FRAME IS FITTED TO THE COLUMN, NOT CENTRED INSIDE IT.
   `place-items: center` over a fixed-width child does not shrink the child: it
   centres it, falls back to start-alignment the moment it overflows, and
   `overflow: hidden` then slices the right-hand edge. Measured in Chromium at
   960px, the artboard read "EDGE TO" with "EDGE" sheared off — a cropped
   picture on the one surface whose job is an accurate picture of what ships.
   The host renders at natural size and scales into this box instead. */
.rr-preview__art {
  display: block;
  width: 100%;
  max-width: 460px;
  overflow: hidden;
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: var(--c-r, 9px);
  background: var(--c-note-bg, #f4f2f6);
}

.rr-preview__art > * {
  width: 100%;
}

.rr-preview__frame figcaption,
.rr-preview__nav span {
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-gov-sm, 9.5px);
  letter-spacing: var(--c-gov-track, 0.13em);
  text-transform: uppercase;
  color: var(--c-meta, #767061);
}

.rr-preview__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 12px;
}

.rr-preview__nav button {
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: var(--c-r-sm, 6px);
  padding: 6px 10px;
  background: transparent;
  color: inherit;
  font: 500 var(--c-ui-sm, 12px) / 1 var(--c-sans, system-ui, sans-serif);
  cursor: pointer;
}

.rr-facts {
  display: grid;
  gap: 10px;
  margin: 18px 0 0;
}

.rr-facts > div { display: grid; gap: 2px; }

.rr-facts dt {
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-gov-sm, 9.5px);
  letter-spacing: var(--c-gov-track, 0.13em);
  text-transform: uppercase;
  color: var(--c-meta, #767061);
}

.rr-facts dd {
  margin: 0;
  font: 400 var(--c-ui, 13.5px) / 1.45 var(--c-sans, system-ui, sans-serif);
  overflow-wrap: anywhere;
}

.rr-facts--mono dd {
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-ui-xs, 11px);
}

.rr-release__formats {
  display: grid;
  gap: 8px;
  margin: 0;
  border: 0;
  padding: 0;
}

.rr-release__formats legend {
  padding: 0;
  font-family: var(--c-mono, ui-monospace, monospace);
  font-size: var(--c-gov-sm, 9.5px);
  letter-spacing: var(--c-gov-track, 0.13em);
  text-transform: uppercase;
  color: var(--c-meta, #767061);
}

.rr-release__formats label {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 4px 10px;
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: var(--c-r, 9px);
  padding: 10px 12px;
  cursor: pointer;
}

.rr-release__formats input { grid-row: span 2; }

.rr-release__format-label {
  font: 500 var(--c-ui, 13.5px) / 1.3 var(--c-sans, system-ui, sans-serif);
}

.rr-release__format-detail,
.rr-release__warning,
.rr-release__binding,
.rr-released p,
.rr-record p {
  font: 400 var(--c-ui-sm, 12px) / 1.5 var(--c-sans, system-ui, sans-serif);
  color: var(--c-meta, #767061);
}

.rr-release__warning { margin: 16px 0 0; }
.rr-release__binding { margin: 6px 0 0; }
.rr-released p,
.rr-record p { margin: 0 0 6px; }

.rr__bound {
  border-left: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
}

.rr__bound .rr-facts { margin-top: 0; }

.rr__technical {
  margin-top: 18px;
  border-top: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  padding-top: 12px;
}

.rr__technical summary {
  cursor: pointer;
  font: 500 var(--c-ui-sm, 12px) / 1 var(--c-sans, system-ui, sans-serif);
  color: var(--c-meta, #767061);
}

/* One column below the width three columns need. The steps stay first: the
   sequence is what a narrow screen loses first and needs most. */
@media (max-width: 920px) {
  /* A narrow viewport leaves little to give away, and the scrim's 16px inset
     took the mode below the width of the dock it replaces. 8px still reads as
     a mode over the Studio rather than a page. */
  .rr-scrim { padding: 8px; }

  .rr {
    width: 100%;
    height: 100%;
    max-height: none;
    border-radius: 10px;
  }

  /* One column below the width three columns need — but the stage is the
     surface the step exists for, so it takes what the other two do not.
     Equal auto rows gave the stage a third of the height and cut the
     release preview in half at 390. */
  .rr__body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }

  .rr__steps,
  .rr__bound {
    border: 0;
    border-bottom: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  }

  /* The notes stay: a refusal a narrow screen drops is a refusal nobody
     reads at the width most people hold. */
  .rr__steps { max-height: 40vh; }
}

/* THE GOVERNED CONTROLS THE MODE HOSTS.
 *
 * `GovernedReleaseControls` draws its acts as `.pact`, and every `.pact` rule
 * lives under `.instrument` in `instrument.css`. Copy mounts this mode inside
 * an `.instrument` ancestor and Carousel does not — so on a deck the sign-off,
 * the terminal governance act, rendered as bare 16px body text while the
 * release button on the next step rendered as a button. The mode carries the
 * treatment itself so it looks the same wherever it mounts, and Copy's own
 * `.instrument .pact` rules still win where they apply. */
.rr :is(button.pact) {
  font-family: var(--c-sans, system-ui, sans-serif);
  font-size: var(--c-ui, 13px);
  font-weight: 600;
  color: inherit;
  background: transparent;
  border: 1px solid var(--c-hairline, rgba(33, 29, 21, 0.14));
  border-radius: 7px;
  padding: 8px 14px;
  cursor: pointer;
}

.rr :is(button.pact.primary) {
  background: var(--c-ink, #211d15);
  border-color: var(--c-ink, #211d15);
  color: var(--c-paper, #fbf8f2);
}

.rr :is(button.pact):hover:not(:disabled):not([aria-disabled='true']) {
  border-color: var(--c-ink, #211d15);
}

.rr :is(button.pact):disabled,
.rr :is(button.pact)[aria-disabled='true'] {
  cursor: default;
  opacity: 0.55;
}
.driver-popover{all:unset;font-family:var(--driver-popover-font-family,"Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif);box-sizing:border-box;color:#2d2d2d;z-index:1000000000;background-color:#fff;border-radius:5px;min-width:250px;max-width:300px;margin:0;padding:15px;position:fixed;top:0;right:0;box-shadow:0 1px 10px #0006}.driver-popover-title{zoom:1;margin:0;font-size:19px;font-weight:700;line-height:1.5;display:block;position:relative}.driver-popover-close-btn{all:unset;cursor:pointer;color:#d2d2d2;z-index:1;text-align:center;width:32px;height:28px;font-size:18px;font-weight:500;transition:color .2s;position:absolute;top:0;right:0}.driver-popover-close-btn:hover,.driver-popover-close-btn:focus{color:#2d2d2d}.driver-popover-title[style*=block]+.driver-popover-description{margin-top:5px}.driver-popover-description{zoom:1;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.5}.driver-popover-footer{text-align:right;zoom:1;justify-content:space-between;align-items:center;margin-top:15px;display:flex}.driver-popover-progress-text{color:#727272;zoom:1;font-size:13px;font-weight:400}.driver-popover-footer-btn{all:unset;box-sizing:border-box;color:#2d2d2d;cursor:pointer;zoom:1;background-color:#fff;border:1px solid #ccc;border-radius:3px;outline:0;padding:3px 7px;font-size:12px;line-height:1.3;text-decoration:none;display:inline-block}.driver-popover-footer .driver-popover-btn-disabled{opacity:.5;pointer-events:none}.driver-popover-footer-btn:hover,.driver-popover-footer-btn:focus{background-color:#f7f7f7}.driver-popover-navigation-btns{flex-grow:1;justify-content:flex-end;display:flex}.driver-popover-navigation-btns button+button{margin-left:4px}.driver-popover-arrow{content:"";border:5px solid #fff;position:absolute}.driver-popover-arrow-side-over{display:none}.driver-popover-arrow-side-left{border-top-color:#0000;border-bottom-color:#0000;border-right-color:#0000;left:100%}.driver-popover-arrow-side-right{border-top-color:#0000;border-bottom-color:#0000;border-left-color:#0000;right:100%}.driver-popover-arrow-side-top{border-bottom-color:#0000;border-left-color:#0000;border-right-color:#0000;top:100%}.driver-popover-arrow-side-bottom{border-top-color:#0000;border-left-color:#0000;border-right-color:#0000;bottom:100%}.driver-popover-arrow-side-center,.driver-popover-arrow-none{display:none}.driver-active .driver-overlay{pointer-events:none}.driver-active.driver-no-scroll{overflow:hidden}.driver-active *{pointer-events:none}.driver-active .driver-active-element,.driver-active .driver-active-element *,.driver-popover,.driver-popover *{pointer-events:auto}@keyframes animate-fade-in{0%{opacity:0}to{opacity:1}}.driver-fade .driver-overlay{animation:animate-fade-in var(--driver-animation-duration,.4s) ease-in-out}.driver-fade .driver-popover{animation:animate-fade-in var(--driver-animation-duration,.4s)}.driver-active-element-parent-no-scroll{overflow:hidden!important}.driver-no-interaction,.driver-no-interaction *{pointer-events:none!important}
/*
 * The tour popover, in the product's own dress.
 *
 * driver.js ships candy: white card, 20px radius, blue pill buttons. Every
 * rule here re-states one of those defaults in the app's austere register —
 * `mock.css` tokens, the `.btn sm` silhouette, no ceremony. The overrides
 * live on `.driver-popover.ink-tour` so a driver.js upgrade that changes its
 * base class fails visibly (unstyled candy) rather than silently mixing two
 * design systems.
 */

.driver-popover.ink-tour {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  padding: 14px 16px;
  max-width: 300px;
}

.driver-popover.ink-tour .driver-popover-title {
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

.driver-popover.ink-tour .driver-popover-description {
  font: inherit;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-2);
  margin-top: 6px;
}

.driver-popover.ink-tour .driver-popover-arrow-side-left.driver-popover-arrow {
  border-left-color: var(--surface);
}
.driver-popover.ink-tour .driver-popover-arrow-side-right.driver-popover-arrow {
  border-right-color: var(--surface);
}
.driver-popover.ink-tour .driver-popover-arrow-side-top.driver-popover-arrow {
  border-top-color: var(--surface);
}
.driver-popover.ink-tour .driver-popover-arrow-side-bottom.driver-popover-arrow {
  border-bottom-color: var(--surface);
}

.driver-popover.ink-tour .driver-popover-footer {
  margin-top: 12px;
  gap: 8px;
}

/* The library's buttons, recut to the app's `.btn sm` silhouette. */
.driver-popover.ink-tour .driver-popover-footer button {
  all: unset;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  line-height: 1;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md, 8px);
  color: var(--ink);
  background: var(--surface);
  text-shadow: none;
}

.driver-popover.ink-tour .driver-popover-footer button:hover {
  background: var(--wash, var(--surface-2, var(--surface)));
}

.driver-popover.ink-tour .driver-popover-footer button:focus-visible {
  outline: 2px solid var(--ink-3);
  outline-offset: 1px;
}

/*
 * The only way out of a popover that covers the page.
 *
 * `all: unset` collapsed this to its glyph — a measured 8x14px, against the
 * 24x24 that WCAG 2.5.8 asks for and well under what anybody hits first time.
 * It is also the control the tour focuses on open, so it is the first thing a
 * keyboard user lands on and the first thing a new account sees ringed.
 *
 * The glyph stays 14px; the target around it does not. Centring the `×` in a
 * 28px box keeps the tour's quiet look and gives the press somewhere to land.
 */
.driver-popover.ink-tour .driver-popover-close-btn {
  all: unset;
  cursor: pointer;
  position: absolute;
  top: 4px;
  right: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  font-size: 14px;
  line-height: 1;
  color: var(--ink-4);
}

.driver-popover.ink-tour .driver-popover-close-btn:hover {
  color: var(--ink-2);
}

/*
 * The quiet replay affordance beside a page-head eyebrow. Lives here because
 * it is tour furniture, not page furniture — every tab renders the same one.
 */
.tourhelp {
  all: unset;
  cursor: pointer;
  font: inherit;
  font-size: 11px;
  color: var(--ink-4);
  white-space: nowrap;
  margin-left: 10px;
}

.tourhelp:hover,
.tourhelp:focus-visible {
  color: var(--ink-2);
  text-decoration: underline dotted;
}
/*
 * The document drop target — the one surface in the product that is allowed to
 * dominate its page, because it exists only while the page has nothing else
 * to say. See `dropTarget.tsx` for the state machine; this file draws it.
 *
 * The idle affordance is a slow breath on the border. CSS only, no script and
 * no timer — the settled bans on synthetic delay apply to animation too: the
 * breath communicates "this region is live", not "something is happening",
 * and the moment something IS happening the reading state replaces it with
 * real figures. Guarded for prefers-reduced-motion below, and the guard is
 * load-bearing: a compliance screen that fidgets at somebody who asked it not
 * to is the exact failure `mock.css` documents.
 */

.droptar {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 10px;
  min-height: 42vh;
  padding: clamp(28px, 6vh, 56px) clamp(22px, 4vw, 52px);
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  cursor: pointer;
  animation: droptar-breathe 3.6s ease-in-out infinite;
}

.droptar:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

@keyframes droptar-breathe {
  0%,
  100% {
    border-color: var(--line-strong);
  }
  50% {
    border-color: var(--ink-3);
  }
}

/* Held over: solid, still, and unmistakably about to receive. */
.droptar.armed {
  border-style: solid;
  border-color: var(--ink);
  background: var(--surface-3);
  animation: none;
}

/* Working or offering: the border stops breathing, because from here the
   words on it are facts and movement would compete with them. */
.droptar.working {
  border-style: solid;
  border-color: var(--line-strong);
  cursor: default;
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .droptar {
    animation: none;
  }
}

.droptar-title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}

.droptar-line {
  margin: 0;
  max-width: 66ch;
  font-size: 13.5px;
  color: var(--ink-2);
}

.droptar-quiet {
  margin: 0;
  max-width: 66ch;
  font-size: 12px;
  color: var(--ink-3);
}

/* The equal-weight ways in that are not a drop. A row, not a footnote. */
.droptar-alts {
  margin-top: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-start;
}
/*
 * THE FIVE-TAB PITCH BOARDS' STYLESHEET.
 *
 * Source: `docs/superpowers/mockups/pitch.css`, copied 20 Aug 2026.
 * Generator: `docs/superpowers/mockups/pitch.py`, which splices
 * `src/design/mock.css`, then `pitch-page.css`, then this file.
 * `pitch-page.css` is the board page's own furniture; the app does not import
 * it.
 *
 * Copied whole for the reason `ds.css` and `mock.css` are copied whole: the
 * deciding is what has gone wrong every previous time. See `ds.css`'s header.
 *
 * ---------------------------------------------------------------------------
 * EVERY RULE HERE IS UNDER `.ppboard`
 * ---------------------------------------------------------------------------
 *
 * This file names about forty short generic things — `.body`, `.chip`, `.seg`,
 * `.st`, `.av`, `.lbl`, `.m`, `.cta`, `.srch`, `h1.ans` — and it is loaded by
 * the signed-in shell, whose root carries `.mockroot`. `.m` was already
 * repainting the Desk's "while you were away" rows at 11px; the other
 * thirty-nine were waiting for the first ported screen to name an element
 * `body` or `chip`.
 *
 * So `pitch.py` writes its board wrapper as `<div class="mockroot ppboard
 * tHome">` (:1188) and every rule below is `.mockroot.ppboard …` or
 * `.tHome.ppboard …`. A screen the port has not reached carries no `ppboard`
 * and matches none of them. `ds.css` is deliberately not scoped this way — its
 * primitives have to work on unported screens, which is what Phase 0b is for.
 *
 * If any of it is wrong it is wrong in `pitch.py`. Do not edit this file to
 * fix a screen.
 */
/* ===========================================================================
   INKSTAND — the five tabs. 19 Aug 2026.
   One material (paper on a desk), five different objects made from it.
   Built on src/design/mock.css, spliced unmodified.
   Colour law: --flag = stops a release / flagged copy, and nothing else.

   THE BOARD ROOT CLASS IS `.ppboard`.
   Every rule below is written `.mockroot.ppboard …` or `.tHome.ppboard …`.
   This file is copied whole into src/design/pitch.css and loaded by the
   signed-in shell, and it names about forty short generic things — `.body`,
   `.chip`, `.seg`, `.st`, `.av`, `.lbl`, `.m`, `.cta`, `.srch`, `h1.ans` —
   under `.mockroot`, which is the shell root. `.m` was already repainting the
   Desk's "while you were away" rows at 11px; the rest were waiting for
   the first ported screen to name an element `body` or `chip`. `.ppboard` is
   carried only by a board wrapper that pitch.py writes (:1184), so a screen
   the port has not reached cannot match any of them.

   ds.css is deliberately NOT scoped this way: its primitives have to work on
   unported screens, which is the whole point of Phase 0b.
   =========================================================================== */
/* The board's own page furniture — `html,body`, `.pp*`, `.ico` — lives in
   pitch-page.css, which pitch.py splices and the app never imports. */

/* ---------- the shell, identical on every tab ----------------------------- */
.mockroot.ppboard .sh{height:56px;background:var(--surface);border-bottom:1px solid var(--line);
              display:flex;align-items:center;gap:24px;padding:0 24px;flex:none}
/* The masthead mark WAS a 20px conic-gradient disc on this line. It is the
   owner's wordmark now and it is at the FOOT of this file — see MASTHEAD MARK. */
.mockroot.ppboard .sh-n{display:flex;gap:4px}
.mockroot.ppboard .sh-n a{display:flex;align-items:center;gap:7px;font-size:14px;color:var(--ink-2);
                  text-decoration:none;padding:7px 12px;border-radius:var(--r-sm)}
.mockroot.ppboard .sh-n a.on{background:var(--ink);color:var(--paper);font-weight:600}
.mockroot.ppboard .sh-r{margin-left:auto;display:flex;align-items:center;gap:11px}
.mockroot.ppboard .sh-b{border:1px solid var(--line-strong);border-radius:var(--r-sm);padding:6px 11px;
                font-size:13px;display:flex;align-items:center;gap:7px}
.mockroot.ppboard .sh-b i{width:11px;height:11px;border-radius:3px;display:block}
.mockroot.ppboard .sh-new{background:var(--ink);color:var(--paper);border-radius:var(--r-sm);padding:7px 13px;
                  font-size:13px;font-weight:600;display:flex;align-items:center;gap:6px}
/* The ring is `var(--line)` for the reason ds.css's `.avx` carries the same
   note: ink at 12% is within a point of `--line` over `--surface` in the light
   theme and 1.01:1 over it in the dark one, so the face had no edge on a dark
   screen. The masthead avatar is live on the ported Home.

   `place-items`, `font-family`, `font-size`, `font-weight`, `color` and
   `position` are mock.css's own `.av` (`mock.css:467`), written down here so
   the face's type does not depend on which other file is loaded. `#fff` and
   not `--paper`: the ground is a saturated brand hue in both themes, the same
   reason ds.css's `.frame2` keeps its white.
   `display` was `inline-block`, which is right for a disc carrying a picture
   and cannot centre initials; `grid` with `place-items` is mock.css's own
   answer and every board here draws its faces inside a flex row, where the
   two blockify identically. Tested: all 25 boards unmoved. */
.mockroot.ppboard .av{border-radius:50%;background-size:cover;background-position:center;display:grid;
              place-items:center;font-family:var(--sans);font-size:11px;font-weight:600;color:#fff;
              position:relative;flex:none;box-shadow:0 0 0 1px var(--line)}
.mockroot.ppboard .av.s{width:20px;height:20px} .mockroot.ppboard .av.m{width:28px;height:28px}
.mockroot.ppboard .av.l{width:34px;height:34px}
.mockroot.ppboard .body{flex:1;overflow:hidden;padding:30px 32px}
.mockroot.ppboard .lbl{font-family:var(--sans);font-size:10.5px;
               color:var(--ink-2);margin:0 0 12px}
.mockroot.ppboard h1.ans{font-size:30px;letter-spacing:-.03em;margin:0;line-height:1.14}
.mockroot.ppboard .st{font-size:12.5px}
.mockroot.ppboard .st.stop{color:var(--flag);font-weight:600}
.mockroot.ppboard .st.judge{color:var(--judge)} .mockroot.ppboard .st.clear{color:var(--cleared)}
/* `.m` IS META TEXT AND `.av.m` IS A MEDIUM AVATAR: one name, two objects, the
   same fault `.cp` had. On the board the faces carry pictures and no words, so
   nothing showed. In the app the face draws initials when there is no picture,
   and these two rules were repainting them in mono at 11px in `--ink-2` on a
   brand-coloured disc; `Shell.tsx:624-634` forces the font, the weight and the
   colour back inline, and that is what `:not(.av)` is standing in for. An
   avatar is never meta text. */
/* `.m` IS TWO OBJECTS AND THIS IS THE ONE SEAM THEY MEET ON.
   Here it is meta text — sans, 11px, `--ink-2`. In `calm.css` it is the text
   column of a row: `.c-row2 > .m{min-width:0;flex:1}` (calm.css:1740, and the
   only `.m` in that file). The four Rules sections calm still draws sit inside
   a `.ppboard` root, so this rule reached them at (0,3,0) against calm's
   (0,2,0) and set every sentence in a `.c-row2` in the mono it then carried,
   which broke into four lines and read as a stack trace. `Rules.tsx:2623` (`ROW2_TEXT`)
   is the inline undo that is now removable.
   The exclusion names the slot, not the sheet: `.m` inside `Sources`' rows and
   `Import`'s notes IS this object and keeps this type. Same fault as `.cp`
   above, and the same shape of answer — say which `.m` is not ours. */
.mockroot.ppboard .m:not(.av):not(.c-row2>*){font-family:var(--sans);font-size:11px;color:var(--ink-2)}
/* THE TRANSPARENT EDGE, so a filled button and a bordered one are one height.
   `.cta` declared no border and `.gh` beside it declares 1px, which made them
   38.92 and 40.92. Where the board puts them in one flex row (Record's "Open
   the carousel" next to "Export entry") the row stretched both and the gap was
   invisible; a `.cta` standing on its own is 2px short of every other control
   around it. ds.css:221 gives `.b` `1px solid transparent` for exactly this,
   which is why a ported primary measured 40.92 against this board's 38.92 and
   P3-b had to log the difference rather than match it (P3-b report, §4). Same
   line here, so the board and the button are the same object again.
   `.cta.off` below already declares its own border and does not move. */
.mockroot.ppboard .cta{background:var(--ink);color:var(--paper);border-radius:var(--r-sm);padding:9px 15px;
               font-size:13.5px;font-weight:600;display:inline-flex;align-items:center;gap:7px;
               border:1px solid transparent}
.mockroot.ppboard .gh{border:1px solid var(--line-strong);border-radius:var(--r-sm);padding:9px 14px;
              font-size:13.5px;color:var(--ink-2);display:inline-flex;align-items:center;gap:7px;
              background:var(--surface)}
.mockroot.ppboard .srch{display:flex;align-items:center;gap:9px;border:1px solid var(--line-strong);
                border-radius:var(--r-sm);padding:8px 12px;background:var(--surface);min-width:250px}
.mockroot.ppboard .srch input{border:0;outline:0;flex:1;font-size:13.5px;font-family:var(--sans);background:none}
.mockroot.ppboard .seg{display:flex;border:1px solid var(--line-strong);border-radius:var(--r-sm);
               overflow:hidden;background:var(--surface)}
.mockroot.ppboard .seg button{border:0;background:none;padding:8px 11px;font-size:12.5px;color:var(--ink-2);
                      border-right:1px solid var(--line);display:flex;align-items:center;gap:6px}
.mockroot.ppboard .seg button:last-child{border-right:0}
.mockroot.ppboard .seg button.on{background:var(--ink);color:var(--paper);font-weight:600}
/* ONE NAME PER OBJECT: THE FILTER CHIP IS `.cp`.
   It was `.chip` here and `.cp` in ds.css — the same object, declaration for
   declaration, under two names — while `.cp` ALSO named Work's calendar entry
   below. So a 0b `Chip` (`system.tsx:2701`, which emits `cp`) rendered as a
   calendar entry on the Work tab and nowhere else, which is why Work's port
   could not use it (P2-Work, generator defect 1). The calendar entry is `.ce`
   now and this is the chip.
   `.chip` STAYS IN THE SELECTOR LIST: the ported Work screen draws `chip`
   today (`workViews.tsx:397-410`) and belongs to another contract, so dropping
   the name would unstyle it the moment this file is copied.
   `font-weight:500` is new here and is not a change: the board's chip was
   taking it from mock.css's own `.chip`, which this rule did not redeclare.
   Measured on the board before and after — 500 either way. */
/* AND THE FULL SET, so nothing else that names an element `chip` can reach it.
   `bench.css:292` declares `.chip` bare — mono, 10px, .11em, uppercase,
   nowrap, inline-flex — and is loaded on every signed-in route. This rule set
   border, radius, padding, size, colour and ground and nothing else, so the
   editor's chip won family, tracking, case and wrapping: measured on
   /app?preview, SF Mono / 1.375px / uppercase / nowrap against the board's
   Avenir Next / normal / none / normal (P2-Work, four things the pairs
   caught, 1). `display`, `align-items` and `gap` are ds.css's `.cp` — the
   chip carries a count in a `<b>` — and the board's chips have no count, so
   they draw the same either way.
   `cursor` was the one property of the set still missing. A board chip is an
   inert `<span>` and reads `auto`; the app draws it on a `<button>`, which the
   agent stylesheet gives `default`, and the only reason the ported filter row
   showed a hand was `bench.css:292`'s bare `.chip` — the leak this rule set
   exists to stop. Declared, so a `.cp` that is not also a `.chip` still says
   it can be pressed (measured on the board: auto -> pointer, no pixel moves). */
.mockroot.ppboard .cp,.mockroot.ppboard .chip{border:1px solid var(--line-strong);border-radius:99px;
                padding:5px 12px;font-size:12.5px;color:var(--ink-2);background:var(--surface);
                font-weight:500;font-family:var(--sans);letter-spacing:normal;text-transform:none;
                white-space:normal;display:inline-flex;align-items:center;gap:6px;cursor:pointer}
/* THE STATE TAG'S OWN BASE, which this file never had.
   `.tg` here is colour and ground and no box: in the design file that lands on
   the card's inherited sans and reads "Stops". `ds.css:319` declared `.tg`
   bare — inline-flex, mono, 10.5px, .11em, uppercase, 4px 9px, 3px radius — so
   the identical markup in the app read "STOPS" in a pill (P2-Work, 2). It is
   sans at 12 in sentence case there now; the box is not, and that is what
   these values undo. It sits HERE, above `.tSet.ppboard .tg` and
   `.tPieceC.ppboard .cv-hd .tg`, so those two keep their own box. */
.mockroot.ppboard .tg{display:inline;align-items:normal;gap:normal;font-family:inherit;
              font-size:inherit;letter-spacing:normal;text-transform:none;padding:0;border-radius:0}
.mockroot.ppboard .cp.on,.mockroot.ppboard .chip.on{background:var(--ink);color:var(--paper);
                border-color:var(--ink);font-weight:600}

/* =========================== HOME — a desk, laid out ======================
   Modules of different sizes, chosen and ordered by rule. Nothing else in the
   product looks like this, because nothing else is composed at runtime.      */
.tHome.ppboard .body{background:var(--paper);padding:26px 30px;display:flex;flex-direction:column}
.tHome.ppboard .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px;flex:1;
             grid-auto-rows:min-content}
.tHome.ppboard .mod{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
            padding:17px 18px;box-shadow:0 1px 2px rgba(23,21,28,.04)}
/* THE URGENT MODULE'S EDGE WAS PICKED AGAINST THE LIGHT WASH AND STAYED THERE.
   `--flag-wash` flips #FDEBF4 -> #2C0D1E with the theme; `#efbdd6` does not. A
   background paints under its own border, so the ground this edge is read
   against is the module's first gradient stop, which is that wash. Measured
   there, light then dark: 1.42 -> 10.92. A hairline on the light page and, on
   the dark one, a pink wire round a near-black card, louder than anything
   inside it. The same defect ds.css:386 fixed on `.bn.stop`, and the same
   correction: derive the edge from the wash's own hue so it turns over with the
   ground. 1.40 / 1.31, against the plain `.mod`'s 1.28 / 1.25. */
.tHome.ppboard .mod.urgent{border-color:color-mix(in srgb,var(--flag) 20%,var(--flag-wash));
                   background:linear-gradient(180deg,var(--flag-wash),var(--surface) 60%)}
/* THE MODULE TITLE IS NAMED, so the component picks its own heading level.
   This was `h5` alone — an element selector, so the tag was fixed by this
   stylesheet and a ported Home had to draw an `h5` under the board's own `h1`.
   That is a four-level jump: axe reports it as `heading-order`, and it is a
   real cost to anybody moving through the screen by heading. `Desk.tsx:297-306`
   carries the `role="heading" aria-level={2}` workaround that says so (P1
   report, deviation 11).
   `h5` STAYS IN THE SELECTOR LIST beside `.mod-t`. Dropping it would unstyle
   every module title on the ported Home the moment this file is copied, and
   the screen belongs to another contract; the class is what the next touch of
   `Desk.tsx` moves to, and the board keeps its `h5`. */
.tHome.ppboard .mod .mod-t,.tHome.ppboard .mod h5{margin:0 0 3px;font-size:15px;
                                          letter-spacing:-.01em}
/* 10.5, NOT 9.5. `accessibility.test.tsx`'s floor now loads this file, and
   Home's "why it is on screen" line is the first thing it caught here. That
   line is the whole argument for a composed board — a module that cannot say
   why it is on screen is a widget — so it is not a caption that may be small. */
.tHome.ppboard .mod .why{font-family:var(--sans);font-size:10.5px;
                 color:var(--ink-3);display:block;margin-bottom:12px}
.tHome.ppboard .mod.urgent .why{color:var(--on-flag-wash)}
.tHome.ppboard .pc{display:flex;align-items:center;gap:11px;padding:9px 0;border-top:1px solid var(--line-soft)}
.tHome.ppboard .pc:first-of-type{border-top:0}
.tHome.ppboard .pc b{font-size:13.5px;font-weight:500;flex:1;white-space:nowrap;overflow:hidden;
             text-overflow:ellipsis}
.tHome.ppboard .big{font-size:40px;letter-spacing:-.03em;line-height:1;display:block}
.tHome.ppboard .big.stop{color:var(--flag)}
.tHome.ppboard .sub{font-size:13px;color:var(--ink-2);line-height:1.5;margin:8px 0 0}

/* =========================== MAKE — two doors ============================= */
.tMake.ppboard .body{padding:0;display:grid;grid-template-columns:1fr 1fr}
/* The four properties a modal scrim called `.door` would otherwise supply.
   `bench.css:1811` is scoped to `.bench-page` now, but the name is a good one
   and the next file to use it should not be able to lay these two out at 0,0
   again (P2-Make §2C). */
.tMake.ppboard .door{padding:56px 52px;display:flex;flex-direction:column;justify-content:center;
             align-items:normal;position:static;inset:auto;z-index:auto;
             border-right:1px solid var(--line);background:var(--surface)}
.tMake.ppboard .door:last-child{border-right:0;background:var(--surface-2)}
.tMake.ppboard .door h2{font-size:34px;letter-spacing:-.03em;margin:0 0 10px}
.tMake.ppboard .door p{font-size:15px;color:var(--ink-2);margin:0 0 28px;line-height:1.55}
.tMake.ppboard .prev{border:1px solid var(--line-strong);border-radius:var(--r);overflow:hidden;
             box-shadow:var(--shadow-3);margin-bottom:28px}
.tMake.ppboard .tpl{display:flex;gap:10px}
.tMake.ppboard .tpl div{flex:1;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden;
                background:var(--surface)}
/* `.cap` IS MOCK.CSS'S NAME TOO (`mock.css:131`, the card caption row), and
   every one of its six declarations is load-bearing on this board — tested by
   neutralising them one at a time and re-rendering: Make moves on
   `margin-bottom`, Work·Gallery on `align-items`, `gap` and `margin-bottom`,
   Work·Board on all five. So they are written down here rather than borrowed,
   and a ported screen no longer depends on mock.css being loaded first
   (P2-Make §2C, P2-Work). */
.tMake.ppboard .tpl .cap{padding:8px 9px;font-size:11.5px;line-height:1.3;display:flex;align-items:baseline;justify-content:space-between;gap:18px;margin-bottom:13px;flex-wrap:wrap}

/* =========================== WORK — the collection ======================== */
.tWork.ppboard .body{padding:0;display:flex;flex-direction:column}
.tWork.ppboard .bar2{padding:20px 30px 16px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
             border-bottom:1px solid var(--line);background:var(--surface)}
.tWork.ppboard .scroll{flex:1;overflow:hidden;padding:20px 30px;background:var(--paper)}
.tWork.ppboard .gal{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
.tWork.ppboard .it{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
           overflow:hidden;box-shadow:0 1px 2px rgba(23,21,28,.05)}
.tWork.ppboard .it .cap{padding:10px 11px;display:flex;align-items:baseline;justify-content:space-between;gap:18px;margin-bottom:13px;flex-wrap:wrap}
.tWork.ppboard .it .cap b{display:block;font-size:12.5px;font-weight:500;line-height:1.35;margin-bottom:7px}
.tWork.ppboard .it .cap .r{display:flex;align-items:center;gap:7px}
.tWork.ppboard .lst{border-top:1px solid var(--line)}
.tWork.ppboard .lr{display:grid;grid-template-columns:34px 1fr 150px 110px 120px;gap:16px;align-items:center;
           padding:11px 0;border-bottom:1px solid var(--line-soft)}
/* 10.5, the floor. `.lh` is the work list's column header; `.rh` below is the
   rule book's, and the raise went on to that one alone. Identical object, two
   screens — `workViews.tsx:947` draws this at ?view=list. */
.tWork.ppboard .lh{display:grid;grid-template-columns:34px 1fr 150px 110px 120px;gap:16px;padding:0 0 10px;
           font-family:var(--sans);font-size:10.5px;
           color:var(--ink-3)}

/* =========================== RULES — a rule book ========================== */
/* THE RAIL RUNS TO THE BOTTOM OR IT IS NOT A RAIL.
   `.mockroot.ppboard .body` above is `flex:1`, which is a property of the
   BOARD PAGE's frame: `pitch-page.css`'s `.pp-a .mockroot` is a 900px flex
   column, so `flex:1` fills it. A ported screen's root is a plain block, so
   `flex:1` does nothing there and the row is as tall as whatever is in it. On
   Coverage — seven rows, no book below them — the ground and the hairline
   stopped 322px short of the bottom of the screen and the rail read as a card
   that had run out (measured on
   /app/b/…/rules?preview&section=coverage: body 424 in a root of 746).
   A floor, not a cap: content taller than the screen still grows the row and
   the screen still scrolls. `pitch-page.css` takes the floor back off, because
   there `100%` is the whole 900 including the masthead sitting above this. */
.tRules.ppboard .body{padding:0;display:grid;grid-template-columns:216px 1fr;min-height:100%}
.tRules.ppboard .rail{border-right:1px solid var(--line);background:var(--surface);padding:24px 0}
.tRules.ppboard .rail a{display:flex;align-items:center;gap:10px;padding:9px 22px;font-size:13.5px;
                color:var(--ink-2);text-decoration:none}
.tRules.ppboard .rail a.on{background:var(--surface-3);color:var(--ink);font-weight:600;
                   box-shadow:inset 2px 0 0 var(--ink)}
.tRules.ppboard .rail a b{margin-left:auto;font-family:var(--sans);font-size:11px;color:var(--ink-3);font-weight:400}
/* 10.5, same floor. These two words are how the rail says which half of the
   rule set a door belongs to. `.tSet .rail .g` was the identical declaration
   left at 9.5, on a board Phase 5 had not ported when this was written; it is
   ported, and both say 10.5 now. */
.tRules.ppboard .rail .g{font-family:var(--sans);font-size:10.5px;
                 color:var(--ink-3);padding:18px 22px 7px;display:block}
.tRules.ppboard .main{padding:26px 30px;overflow:hidden;background:var(--paper)}
.tRules.ppboard .book{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
              overflow:hidden;margin-top:16px}
.tRules.ppboard .rw{display:grid;grid-template-columns:1fr 128px 92px 104px;gap:16px;align-items:center;
            padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.tRules.ppboard .rw:last-child{border-bottom:0}
.tRules.ppboard .rw q{font-family:var(--serif);font-size:14.5px;line-height:1.42;quotes:none;color:var(--ink)}
/* 10.5, same floor. A column header names what the column holds and there is
   no second place on the screen that says it. */
.tRules.ppboard .rh{display:grid;grid-template-columns:1fr 128px 92px 104px;gap:16px;padding:11px 18px;
            background:var(--surface-2);border-bottom:1px solid var(--line);font-family:var(--sans);
            font-size:10.5px;color:var(--ink-3)}
/* THE SELECTION TRACK. This book had none while the Work list did
   (`.lr`/`.lh` above), and the screen that replaced the old Rules page has
   always had bulk severity moves, so P3-a drew the tick on an inline five-track
   override of `.rw` (`Rules.tsx:2577`, `SELECT_GRID`) and reported the gap
   rather than editing this file. It is the board's, declared here.
   On `.book`, not on the rows: a seat that cannot act is shown no ticks at all,
   and the header and the rows have to agree about how many tracks there are.
   `.ckx` is already the board's tick (below, under `.mockroot.ppboard`). */
.tRules.ppboard .book.pick .rh,.tRules.ppboard .book.pick .rw{grid-template-columns:26px 1fr 128px 92px 104px}
.tRules.ppboard .rw.sel{background:var(--beam-wash)}

/* =========================== RECORD — the register ======================== */
.tRec.ppboard .body{padding:0;display:grid;grid-template-columns:1fr 400px}
.tRec.ppboard .reg{padding:26px 30px;overflow:hidden;background:var(--paper)}
.tRec.ppboard .rr{display:grid;grid-template-columns:96px 1fr 150px 120px;gap:14px;align-items:center;
          padding:12px 0;border-bottom:1px solid var(--line-soft)}
.tRec.ppboard .rr .when{font-family:var(--sans);font-size:11px;color:var(--ink-3)}
.tRec.ppboard .rr b{font-size:13.5px;font-weight:500}
.tRec.ppboard .side{border-left:1px solid var(--line);background:var(--surface);padding:26px 24px;
            overflow:hidden}
.tRec.ppboard .ev{border:1px solid var(--line-strong);border-radius:var(--r);overflow:hidden;margin-top:14px}
.tRec.ppboard .ev .top{padding:12px 14px;background:var(--surface-2);border-bottom:1px solid var(--line);
               display:flex;align-items:center;gap:9px;font-size:12.5px}
.tRec.ppboard .ev .art{display:block}
.tRec.ppboard .kv{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--line-soft);
          font-size:13px}
.tRec.ppboard .kv span:first-child{color:var(--ink-2)}

/* ===================== EVERY RULE IN THIS FILE UNDER 10.5 =================
   Swept declaration by declaration, and each one decided rather than counted.
   The product's floor is 10.5 (`accessibility.test.tsx`) and it exempts
   DRAWINGS — a monogram or a miniature whose meaning is also on the screen in
   readable type. The exemption is not "it is small"; it is "it is a picture of
   something, and the thing it depicts is legible elsewhere".

   RAISED to 10.5, because they are text a person reads:
     `.tRules .sug .from`   the suggestion's provenance line
     `.tSet .rail .g`       the settings rail's group heading
     `.tWork .embl`         the calendar's embargo link

   DRAWINGS, and staying under the floor. The two artwork thumbnails are the
   carousel slide the customer made, drawn at 1/4 and 1/12 scale — the ground
   is a colour the customer picked and the type on them is the customer's own
   copy, reproduced, not chrome. Both mounts are `aria-hidden="true"`
   (`Desk.tsx:283`, `Make.tsx:1507`) and the deck's name is spelled out in ink
   under the tile, which is where it is read. The floor sweep skips an
   `aria-hidden` subtree for exactly this reason, so no guard has to be widened
   to allow them:
     `.art .ft` 8, `.art-f .ix` 7.5, `.art-f .bm` 7, `.art.h200 .bm` 10
     `.art-p .lh2 b` 7.5, `.art-p .tx` 8.5, `.art.h240 .lh2 b` 9.5
   `.art-p` is drawn `.sq` on every mount and `.art.sq *{display:none}` hides
   its children outright, so those three render nothing at all today.

   `.cvf.sm` is the filmstrip's frame at 62x78 — a thumbnail of a 1080x1350
   artboard, 5.7% of the original. Its `.h` 6.5, `.s` 3.6, `.f` 3.4, `.bm` 3.4
   and `.n` 4, and the caption cell's `.cvf.cap .n` 3.6 (`cvcap()` draws it at
   `sm` and at no other size), are the artboard's own type scaled with it; the
   frame actually read is `.cvf.lg` beside it at 31/14. Board-only: nothing in
   `src/` mounts `.cvf`.

   `.fnd2 .src3` (9.5) and `.tPieceC .fs .num` (9) are board-only too — no
   `.tsx` renders either class at this head. They are named here so that
   whoever ports the finding card or the filmstrip raises them on the way in
   rather than discovering the floor afterwards, which is what happened to
   `.sug .from` and to `.embl`.
   ========================================================================= */

/* shared artefact rendering */
.mockroot.ppboard .art{position:relative;overflow:hidden;display:block;background:var(--surface)}
.mockroot.ppboard .art-f{color:#fff;padding:13px;display:flex;flex-direction:column}
/* colour set ON the element, not inherited: a tab-level `p` rule beats an
   inherited colour every time, and Make's door prose was greying the headline
   on its own preview. */
.mockroot.ppboard .art-f .hl{font-family:var(--serif);line-height:1.14;margin:0;font-size:15px;
                     color:#fff}
.mockroot.ppboard .art-p .tx{color:var(--ink-2)}
.mockroot.ppboard .art-f .ft, .mockroot.ppboard .art .ft{margin-top:auto;display:flex;align-items:center;gap:6px;font-size:8px;
                     letter-spacing:.09em;text-transform:uppercase;opacity:.85}
.mockroot.ppboard .art-f .bm, .mockroot.ppboard .art .bm{width:12px;height:12px;border-radius:3px;background:rgba(255,255,255,.9)}
.mockroot.ppboard .art-f .ix{margin-left:auto;font-family:var(--mono);font-size:7.5px}
.mockroot.ppboard .art-p{padding:13px;display:flex;flex-direction:column}
.mockroot.ppboard .art-p .lh2{display:flex;align-items:center;gap:6px;padding-bottom:8px;
                      border-bottom:1px solid var(--line);margin-bottom:9px}
.mockroot.ppboard .art-p .lh2 i{width:11px;height:11px;border-radius:3px;display:block}
.mockroot.ppboard .art-p .lh2 b{font-size:7.5px;letter-spacing:.12em;text-transform:uppercase;
                        color:var(--ink-3);font-weight:500}
.mockroot.ppboard .art-p .tx{font-size:8.5px;line-height:1.6;color:var(--ink-2);margin:0}
.mockroot.ppboard .art.h120{height:120px} .mockroot.ppboard .art.h150{height:150px}
.mockroot.ppboard .art.h200{height:200px} .mockroot.ppboard .art.h240{height:240px}
.mockroot.ppboard .art.sq{width:30px;height:30px;border-radius:4px;border:1px solid var(--line-strong)}
.mockroot.ppboard .art.sq *{display:none}
.mockroot.ppboard .art.h240 .hl{font-size:26px} .mockroot.ppboard .art.h200 .hl{font-size:22px}
.mockroot.ppboard .art.h240 .tx,.mockroot.ppboard .art.h200 .tx{font-size:12.5px;line-height:1.66}
.mockroot.ppboard .art.h240 .lh2 b,.mockroot.ppboard .art.h200 .lh2 b{font-size:9.5px}
.mockroot.ppboard .sq-p{background:var(--surface)}
.mockroot.ppboard .sq-p::after{content:'';position:absolute;inset:6px;border-left:3px solid currentColor}
.mockroot.ppboard .flagw{text-decoration:underline wavy var(--flag);text-underline-offset:3px;
                 text-decoration-thickness:1.3px;text-decoration-skip-ink:none}

/* ---- Work · Board -------------------------------------------------------- */
.tWork.ppboard .kb{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;height:100%}
.tWork.ppboard .col{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);
            padding:12px;overflow:hidden}
/* The board's column name, with the held count in the `<b>` beside it. Same
   header, same floor, on ?view=board (`workViews.tsx:1123`). */
.tWork.ppboard .col h6{margin:0 0 11px;font-family:var(--sans);font-size:10.5px;
               color:var(--ink-2);display:flex;align-items:center;gap:8px}
.tWork.ppboard .col h6 b{margin-left:auto;color:var(--ink);font-weight:600}
.tWork.ppboard .kc{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
           overflow:hidden;margin-bottom:10px}
.tWork.ppboard .kc .cap{padding:9px 10px;display:flex;align-items:baseline;justify-content:space-between;gap:18px;margin-bottom:13px;flex-wrap:wrap}
.tWork.ppboard .kc .cap b{display:block;font-size:12px;font-weight:500;line-height:1.35;margin-bottom:6px}
/* ---- Work · Calendar ----------------------------------------------------- */
/* A FLOOR ON EACH WEEK, NOT ONLY A HEIGHT ON THE GRID.
   `height:100%` resolves here because the board is a fixed 900px box and
   `.scroll` above is a flex child of it with a definite height. In the app
   nothing gives the pane one — `.scroll` is `overflow:hidden`, correct for a
   static board, and the screen root scrolls instead — so the percentage
   resolved against an indefinite height, `1fr` collapsed to content, and a
   month of empty days drew as four 41px strips with the pane empty beneath
   them (measured: grid 203px, week row 41.3px). `minmax` keeps the `1fr`
   behaviour wherever the pane IS definite and stops the collapse where it is
   not. 150px is under this board's own row height at 1440x900 (157.4px
   measured), so nothing here moves. `workViews.tsx:1195` holds the same floor
   inline and this is what it is standing in for (P2-Work generator defect 5). */
.tWork.ppboard .cal{display:grid;grid-template-columns:repeat(7,1fr);
            grid-template-rows:32px repeat(4,minmax(150px,1fr));gap:1px;background:var(--line);
            border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;height:100%}
.tWork.ppboard .cd{background:var(--surface);padding:9px;min-height:0;overflow:hidden}
.tWork.ppboard .cd .n{font-family:var(--sans);font-size:10.5px;color:var(--ink-3);display:block;margin-bottom:7px}
.tWork.ppboard .cd.off{background:var(--surface-2);padding:8px 9px;display:flex;align-items:center}
.tWork.ppboard .cd.off .n{margin:0}
.tWork.ppboard .cd.emb{background:var(--flag-wash)}
/* `.ce`, THE CALENDAR ENTRY. It was `.cp`, which is the filter chip's name in
   ds.css and now here too. `color` is written into the rule because the ink it
   had been taking from `.mockroot.ppboard .cp` belongs to the chip. */
.tWork.ppboard .ce{font-size:10.5px;line-height:1.3;padding:5px 6px;border-radius:3px;margin-bottom:5px;
           color:var(--ink-2);background:var(--surface-3);border-left:2px solid var(--beam)}
.tWork.ppboard .ce.stop{border-left-color:var(--flag);background:var(--flag-wash)}
/* 10.5, not 9. The embargo mark is a LINK on the calendar
   (`workViews.tsx:1266-1271`) carrying the embargo's own name, and nothing
   else on the day cell says which embargo is open — so it is text under the
   product's floor, on a product route, and it has been since the view was
   ported. The floor sweep never saw it: `?view=calendar` was not one of the
   addresses `accessibility.test.tsx` walks, and the two Work views that ARE
   walked draw no `.embl`. The route is on that list now. */
.tWork.ppboard .embl{font-family:var(--sans);font-size:10.5px;
             color:#A4004F}
/* ---- Rules · sources, suggestions, coverage, import ---------------------- */
.tRules.ppboard .src{display:grid;grid-template-columns:1fr 130px 120px 132px;gap:16px;align-items:center;
             padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.tRules.ppboard .src:last-child{border-bottom:0}
.tRules.ppboard .src b{font-size:13.5px;font-weight:500}
/* WAS `.sg`, AND `.sg` IS ds.css's SEGMENTED CONTROL (ds.css:308 — inline-flex,
   a border, a radius, `overflow:hidden`, and `.sg button` putting a divider on
   every child). This page splices mock.css and this file and not ds.css, so the
   board never showed it; the app loads both, and pitch's (0,3,0) only wins the
   declarations it makes. `display` is not one of them, so a suggestion card in
   the app became an inline-flex row with the acts squeezed to slivers. P3-e
   undid it inline.
   The segmented control keeps the name: `sg` is what it is short for, and
   `system.tsx`'s `Segmented` is built on it. This card is `.sug`. Third of the
   same family in this file after `.cp` and `.m` — a two-letter class in a sheet
   that loads beside two others. */
.tRules.ppboard .sug{border-bottom:1px solid var(--line-soft);padding:16px 18px}
.tRules.ppboard .sug:last-child{border-bottom:0}
.tRules.ppboard .sug q{font-family:var(--serif);font-size:15.5px;line-height:1.44;quotes:none;display:block}
/* 10.5, the product's floor. This is the provenance line — where the suggestion
   came from and why it is being offered — and it is the only place on the card
   that says either. `accessibility.test.tsx` floors the product's type at 10.5
   and the sweep could not reach this rule while the card was still `.sg` in the
   app: the selector matched nothing, so the guard reported a pass about a
   9.5px line. `Suggestions.tsx` took `.sug`, the rule landed, and the leaf held
   the floor with an inline `font-size` while reporting it here. Declared now,
   so the leaf can drop it. */
.tRules.ppboard .sug .from{font-family:var(--sans);font-size:10.5px;
                  color:var(--ink-3);margin-top:9px;display:block}
.tRules.ppboard .sug .acts{display:flex;gap:9px;margin-top:12px}
.tRules.ppboard .cov{display:grid;grid-template-columns:190px 1fr 42px;gap:16px;align-items:center;
             padding:10px 0}
.tRules.ppboard .cov i{height:8px;border-radius:4px;background:var(--surface-3);display:block;overflow:hidden}
.tRules.ppboard .cov i u{display:block;height:100%;background:var(--beam)}
.tRules.ppboard .cov i u.thin{background:var(--flag)}
.tRules.ppboard .cov b{font-family:var(--sans);font-size:11px;color:var(--ink-2);text-align:right;font-weight:400}
.tRules.ppboard .drop{border:1.5px dashed var(--line-strong);border-radius:var(--r-lg);padding:40px;
              text-align:center;background:var(--surface)}
/* THE GLYPH WAS NOT CENTRED ANYWHERE, INCLUDING HERE. `text-align:center`
   centres inline boxes and the upload mark is not one: `mock.css:91` ends with
   a bare `svg{display:block}`, and a block box is placed by its margins. So the
   mark sat hard against the left padding edge with the copy centred under it —
   on this board (glyph centre 313 in a box centred on 828) and in the app
   (297 in the same 828), where Tailwind's preflight declares the same thing a
   second time.
   `margin-inline:auto` rather than `display:inline-block`, for two reasons: it
   holds whatever the display is, so neither of those two blanket rules can
   undo it again; and inline-block would put the glyph back on a text baseline
   and add the descender gap under it, which changes the height of the box. */
.tRules.ppboard .drop .ico{margin-inline:auto}
/* ---- Record · the document ---------------------------------------------- */
.tDoc.ppboard .body{padding:0;display:grid;grid-template-columns:1fr 340px}
.tDoc.ppboard .sheet{overflow:hidden;padding:44px 56px;background:var(--surface)}
.tDoc.ppboard .sheet h2{font-family:var(--serif);font-size:27px;font-weight:400;margin:0 0 6px}
.tDoc.ppboard .sheet .meta{font-family:var(--sans);font-size:10.5px;
                   color:var(--ink-3);padding-bottom:20px;border-bottom:2px solid var(--ink);
                   margin-bottom:22px}
.tDoc.ppboard .sec{margin-bottom:20px}
.tDoc.ppboard .sec h3{font-size:12px;font-family:var(--sans);
              color:var(--ink-2);margin:0 0 10px;font-weight:400}
.tDoc.ppboard .sec p{font-family:var(--serif);font-size:14.5px;line-height:1.55;margin:0 0 8px;
             padding-left:16px;border-left:2px solid var(--line-strong)}
.tDoc.ppboard .side{border-left:1px solid var(--line);background:var(--surface-2);padding:26px 24px}
/* ---- Settings ------------------------------------------------------------ */
/* THE RAIL RUNS TO THE BOTTOM HERE TOO. Same fault, same repair, same reason
   as `.tRules .body` above: `.mockroot.ppboard .body` is `flex:1`, which is a
   property of the BOARD PAGE's frame — `pitch-page.css`'s `.pp-a .mockroot`
   is a 900px flex column, so `flex:1` fills it. A ported screen's root is a
   plain block and `flex:1` does nothing there, so the row was as tall as
   whatever was in it. Measured on /app/account/billing?preview: the body was
   411px inside a root of 726, so the rail's ground and its right-hand
   hairline stopped 314px short of the bottom of the screen and the settings
   rail read as a card that had run out.
   A floor, not a cap: content taller than the screen still grows the row and
   `.c-body` still scrolls. `pitch-page.css` takes the floor back off for both
   boards with one rule, because there `100%` is the whole 900 including the
   masthead sitting above this. */
.tSet.ppboard .body{padding:0;display:grid;grid-template-columns:216px 1fr;min-height:100%}
.tSet.ppboard .rail{border-right:1px solid var(--line);background:var(--surface);padding:24px 0}
.tSet.ppboard .rail a{display:flex;align-items:center;gap:10px;padding:9px 22px;font-size:13.5px;
              color:var(--ink-2);text-decoration:none}
.tSet.ppboard .rail a.on{background:var(--surface-3);color:var(--ink);font-weight:600;
                 box-shadow:inset 2px 0 0 var(--ink)}
/* 10.5, the same floor and the same reason as the rule book's rail. The board
   was inconsistent about one declaration written twice: `.tRules .rail .g`
   went to 10.5 and this one, character for character identical, stayed at 9.5
   because Phase 5 had not ported Settings yet and the floor could not reach
   it. It has, and it can. These two words are the only place the rail says
   which half of the account a door belongs to. */
.tSet.ppboard .rail .g{font-family:var(--sans);font-size:10.5px;
               color:var(--ink-3);padding:18px 22px 7px;display:block}
.tSet.ppboard .main{padding:28px 32px;overflow:hidden;background:var(--paper)}
.tSet.ppboard .pr{display:grid;grid-template-columns:34px 1fr 200px 190px 110px;gap:16px;align-items:center;
          padding:13px 18px;border-bottom:1px solid var(--line-soft);background:var(--surface)}
/* Settings' people table carries the third copy of that header. Raised with
   the other two rather than after Phase 5 ports the screen, so the port has
   nothing to correct. */
.tSet.ppboard .ph{display:grid;grid-template-columns:34px 1fr 200px 190px 110px;gap:16px;padding:11px 18px;
          font-family:var(--sans);font-size:10.5px;
          color:var(--ink-3);background:var(--surface-2);border-bottom:1px solid var(--line)}
.tSet.ppboard .card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
            overflow:hidden;margin-top:16px}
.tSet.ppboard .bd{display:grid;grid-template-columns:44px 1fr 130px 120px 100px;gap:16px;align-items:center;
          padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.tSet.ppboard .bd i{width:34px;height:34px;border-radius:var(--r-sm);display:block}

/* ---------------------------------------------------------------------------
   CONTRAST FLOOR. Appended last so nothing later overrides it. Every value
   measured, not judged: --cleared on white is 4.45:1, just under AA, and text
   on a brand ground was being dimmed by opacity.
   --------------------------------------------------------------------------- */
.mockroot.ppboard .st.clear,.mockroot.ppboard .st.g,.mockroot.ppboard .tg.clear{color:#3F5622}
.mockroot.ppboard .art-f,.mockroot.ppboard .art-f .hl,.mockroot.ppboard .art-f .ft,.mockroot.ppboard .art-f .ix,.mockroot.ppboard .art-f .ft *{color:#fff;opacity:1}
.mockroot.ppboard .art-f .ix{color:rgba(255,255,255,.92)}
.mockroot.ppboard .col h6,.mockroot.ppboard .col h6 b,.mockroot.ppboard .lbl,.mockroot.ppboard p.lbl{color:var(--ink-2)}
.mockroot.ppboard .vB-card .m,.mockroot.ppboard .m:not(.av):not(.c-row2>*){color:var(--ink-2)}

/* list selection + bulk, brought over from the system */
.tWork.ppboard .lr,.tWork.ppboard .lh{grid-template-columns:26px 34px 1fr 170px 130px 140px}
.tWork.ppboard .lr.sel{background:var(--beam-wash)}
.mockroot.ppboard .ckx{width:15px;height:15px;border-radius:4px;border:1.5px solid var(--line-strong);
               background:var(--surface);display:block;position:relative}
.mockroot.ppboard .ckx.on{background:var(--ink);border-color:var(--ink)}
/* THE TICK WAS `#fff` AND THE BOX IT SITS IN IS `--ink`, WHICH INVERTS.
   In light that is white on near-black and reads. In dark `--ink` is #f0eef4,
   so the mark was white on white: measured 1.15:1, and a ticked row's only
   per-row signal was a pale empty square. Same fault as the `.bn` edges below
   and the same repair — the mark takes the token that turns over with the box
   it is cut out of. `--surface` on `--ink` is 18.10 light / 15.75 dark. */
.mockroot.ppboard .ckx.on::after{content:'';position:absolute;left:4px;top:1px;width:4px;height:8px;
                         border:solid var(--surface);border-width:0 2px 2px 0;transform:rotate(45deg)}
.mockroot.ppboard .bulkbar{background:var(--ink);color:var(--paper);border-radius:var(--r);padding:9px 13px;
                   display:flex;align-items:center;gap:12px;font-size:13px;margin:0 0 12px}
.mockroot.ppboard .bulkbar .gh{background:color-mix(in srgb,var(--paper) 18%,transparent);border-color:transparent;color:var(--paper)}
/* coverage: checked or not, never a proportional bar */
.tRules.ppboard .cov{grid-template-columns:1fr 130px 96px}

/* ---- the piece: the words, the findings, the release ---------------------- */
.tPiece.ppboard .body{padding:0;display:grid;grid-template-columns:1fr 400px}
.tPiece.ppboard .pc-doc{padding:38px 46px;overflow:hidden;background:var(--surface)}
.tPiece.ppboard .pc-hd{display:flex;align-items:center;gap:14px;padding-bottom:16px;
               border-bottom:1px solid var(--line);margin-bottom:26px}
.tPiece.ppboard .pc-hd .acts2{margin-left:auto;display:flex;gap:9px}
.tPiece.ppboard .pc-hd .gh{padding:6px 11px;font-size:12.5px}
.tPiece.ppboard .pc-doc h2{font-size:25px;letter-spacing:-.02em;margin:0 0 22px}
.tPiece.ppboard .pc-doc p{font-size:18px;line-height:1.8;margin:0 0 18px;max-width:46ch;color:var(--ink)}
.tPiece.ppboard .pc-side{border-left:1px solid var(--line);background:var(--surface-2);padding:22px 20px;
                 display:flex;flex-direction:column;overflow:hidden}
.tPiece.ppboard .pc-top{display:flex;flex-direction:column;gap:5px;padding-bottom:14px;
                border-bottom:1px solid var(--line);margin-bottom:14px}
.tPiece.ppboard .pc-top b{font-size:15px}
.mockroot.ppboard .fnd2{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
                padding:15px 16px;margin-bottom:11px}
.mockroot.ppboard .fnd2.stop{border-left:3px solid var(--flag)}
.mockroot.ppboard .fnd2.judge{border-left:3px solid var(--judge)}
.mockroot.ppboard .fnd2 q{display:block;font-family:var(--serif);font-size:15px;line-height:1.44;
                  quotes:none;margin:9px 0 0;color:var(--ink)}
.mockroot.ppboard .fnd2 .src3{display:block;font-family:var(--sans);font-size:9.5px;
                      color:var(--ink-3);margin-top:9px;line-height:1.5}
.mockroot.ppboard .fnd2 .row2{display:flex;gap:9px;margin-top:12px}
.tPiece.ppboard .pc-foot{margin-top:auto;padding-top:16px;border-top:1px solid var(--line)}
/* MOVED OUT OF `photos.css`, WHICH THE APP DOES NOT IMPORT.
   Both studio boards open `.pc-foot` with this line — an avatar and "Tomasz W
   is waiting since 16 Aug" — and it is a `display:flex` with a gap and a type
   size, none of which is photography. It was declared in `photos.css` because
   the avatar beside it is, and `photos.css` is spliced into the two generated
   pages and nothing else: `Shell.tsx` imports mock, ds, pitch and calm. So a
   ported `.who-line` inherited nothing, the avatar and the sentence stacked as
   two block-level children, and the row broke onto its own line.
   It is `.ppboard`-scoped here like every other rule in this file. `photos.css`
   keeps the photography — `.t-av`, `.avs`, `.shot` and the `ph-f*` data URIs —
   and nothing else moved with it. */
.mockroot.ppboard .who-line{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink-2)}
.mockroot.ppboard .u-stop{text-decoration:underline wavy var(--flag);text-underline-offset:5px;
                  text-decoration-thickness:1.8px;text-decoration-skip-ink:none}
.mockroot.ppboard .u-judge{text-decoration:underline wavy var(--judge);text-underline-offset:5px;
                   text-decoration-thickness:1.8px;text-decoration-skip-ink:none}

/* ===========================================================================
   COLOUR LAW, ENFORCED. Measured, not judged.
   --flag was carrying six meanings: deletes, the release glyph, a changed
   source, an unclaimed item, a coverage gap and numeric counts. A colour that
   means six things means none, and this product cannot afford that one.
   =========================================================================== */
.mockroot.ppboard .st.judge,.mockroot.ppboard .tg.judge,.mockroot.ppboard .st.j{color:#6D5B8F;opacity:1}
.mockroot.ppboard .tg.judge{background:var(--judge-wash);color:#584A75}
.mockroot.ppboard .tg.clear{background:var(--cleared-wash);color:#3F5622}
.mockroot.ppboard .tg.stop{background:var(--flag-wash);color:#A4004F}
/* counts are ink. weight and size carry emphasis, never hue. */
.mockroot.ppboard .rw .st,.mockroot.ppboard .cov b,.mockroot.ppboard .figs b{color:var(--ink)}
.mockroot.ppboard .figs b.stop{color:var(--flag)}
/* a source that CHANGED is news, not a rule stopping copy */
.tRules.ppboard .src .st.stop,.tRules.ppboard .src .tg.stop{background:var(--beam-wash);color:#0B756F}
/* the brand mark, no longer an empty white box */
.mockroot.ppboard .art-f .bm{display:grid;place-items:center;font-size:7px;font-weight:700;
                     color:rgba(23,21,28,.72);font-family:var(--sans)}
.mockroot.ppboard .art.h200 .bm,.mockroot.ppboard .art.h240 .bm{width:18px;height:18px;font-size:10px}
.mockroot.ppboard .art-f .ft{color:rgba(255,255,255,.9)}
.mockroot.ppboard .art-f .ix{color:rgba(255,255,255,.82)}
/* urgency lives on the card. The same literal edge, on `--surface` this time
   rather than a wash: 1.63 light, 11.16 dark. The 3px inset bar is what says
   "this one stops" and it is already `--flag`; the edge only has to hold the
   card. Derived from `--surface` at the same strength, it reads 1.48 / 1.29. */
.tWork.ppboard .it.blocks{border-color:color-mix(in srgb,var(--flag) 22%,var(--surface));
                  box-shadow:inset 3px 0 0 var(--flag)}
/* one card anatomy: the footer is always a second row, status always right */
.tWork.ppboard .it .cap b{display:block;min-height:34px}
.tWork.ppboard .it .cap .r{display:flex;align-items:center;gap:7px;margin-top:2px}
/* the register panel: title was colliding with the brand chip */
.tRec.ppboard .ev .art{padding-bottom:34px}
/* settings: ghost borders were 1.14:1 */
.tSet.ppboard .gh,.tSet.ppboard .pr .gh{border-color:var(--line-strong);color:var(--ink-2)}

/* The final list of things allowed to be magenta:
   1. a finding that stops a release (chip, rail, module)
   2. the squiggle under flagged copy
   3. the count of things that stop a release
   Everything below was borrowing it and is now returned. */
.tWork.ppboard .cd.emb{background:var(--surface-2)}                    /* an embargo is time-bound */
.tWork.ppboard .embl{color:var(--judge)}
.tWork.ppboard .ce.stop{border-left-color:var(--judge);background:var(--judge-wash)}
.tRules.ppboard .cov .st.stop{background:none;color:var(--ink-2);font-weight:600}  /* not-checked ≠ stop */
.tRec.ppboard .rr .st.stop{color:var(--ink-2);font-weight:500}          /* a recorded waiver is not an alarm */
.tPiece.ppboard .pc-top b{color:var(--ink)}                             /* "2 findings" is a count */
.tHome.ppboard .mod .big{color:var(--ink)}
.tHome.ppboard .mod.urgent .big{color:var(--flag)}

/* one card anatomy, whatever the title length: preview, then a fixed two-line
   title, then a footer row that is always in the same place. */
.tWork.ppboard .it{display:flex;flex-direction:column}
.tWork.ppboard .it .art{flex:none}
.tWork.ppboard .it .cap{display:flex;flex-direction:column;flex:1;padding:11px 12px 12px}
.tWork.ppboard .it .cap b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
                  overflow:hidden;min-height:35px;margin-bottom:0}
.tWork.ppboard .it .cap .r{margin-top:auto;padding-top:10px}
.tWork.ppboard .gal{grid-template-columns:repeat(5,1fr);gap:14px;align-items:stretch}
/* the preview no longer leaves a void under short copy */
.mockroot.ppboard .art-p .tx{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;
                     overflow:hidden}

/* what adopting this rule would do to the ten pieces already in flight */
.tRules.ppboard .sug{padding-bottom:16px}
.tRules.ppboard .imp{margin:12px 0 14px;padding:11px 13px;border-radius:8px;background:var(--surface-2);
             border:1px solid var(--line)}
.tRules.ppboard .impn{font:600 12px/1 var(--font-gov);letter-spacing:.04em;text-transform:uppercase;
              color:var(--ink-2)}
.tRules.ppboard .impn b{font-size:15px;color:var(--ink);margin-right:5px;font-family:var(--font-text)}
.tRules.ppboard .impn b.stop{color:var(--flag)}
.tRules.ppboard .dot{margin:0 9px;color:var(--line-2)}
.tRules.ppboard .impq{margin-top:9px;font:italic 14px/1.5 var(--font-rule);color:var(--ink);
              display:flex;align-items:baseline;gap:12px}
.tRules.ppboard .impp{font:500 11px/1 var(--font-gov);letter-spacing:.05em;text-transform:uppercase;
              color:var(--ink-3);white-space:nowrap;margin-left:auto}

/* Unavailable actions carry a pale ground and real ink, never opacity —
   opacity fades the label and the border at the same rate, so the control
   stops reading as a control before it stops reading as available. */
.mockroot.ppboard .gh.off,.mockroot.ppboard .b.dis{
  background:var(--surface-3);border-color:var(--line);color:var(--ink-3);
  opacity:1;cursor:not-allowed}
/* the 10px caption numeral was the last sub-AA reading in the set */
.mockroot.ppboard .cp b,.mockroot.ppboard .cp .n{color:var(--ink-2)}
.mockroot.ppboard .cp{color:var(--ink-2)}
/* AND THE STATE THAT LINE TOOK WITH IT.
   `.cp.on` above paints `--ink` ground and `--paper` label; the line above is
   (0,3,1) on the `<b>` inside it and comes later, so the count kept `--ink-2`
   and was read on the ink ground: 1.98:1 light, 1.68:1 dark, measured on
   /app/b/…/rules with "Stops a release" pressed. A pressed chip is the one
   state where the count matters, because it is the count being filtered to.
   `inherit`, not a second literal — the chip's own colour is already the
   right one in both themes and this stops the pair drifting apart again. */
.mockroot.ppboard .cp.on b,.mockroot.ppboard .cp.on .n,
.mockroot.ppboard .chip.on b,.mockroot.ppboard .chip.on .n{color:inherit}

.mockroot.ppboard .cta.off{background:var(--surface-3);border:1px solid var(--line);
  color:var(--ink-3);opacity:1;cursor:not-allowed;box-shadow:none}

/* "Unclaimed" says nobody has picked this up. That is a fact about people,
   not a rule stopping copy — the card's own rail already carries the stop. */
.tWork.ppboard .it .st.stop{color:var(--judge)}
.mockroot.ppboard .st:not(.stop){color:var(--ink-2)}
/* AND THE ONE STATE THAT LINE WAS NEVER MEANT TO TAKE.
   `.mockroot.ppboard .st:not(.stop)` is (0,4,0), the same weight as
   `.mockroot.ppboard .st.judge` above it, and it comes later — so "Findings to
   settle" painted `--ink-2` and was indistinguishable from "Not checked" on
   Work's list and gallery, in both themes (measured: rgb(74,70,85) light,
   rgb(189,184,200) dark, identical to the draft row beside it). `.st.clear`
   escapes it further down and needed nothing; judge did not.
   `--judge` and not a literal, because this word is read on `--paper` in both
   themes: 5.36:1 light, 8.11:1 dark. A person must decide is a state, and a
   state a person cannot see is not one. */
.mockroot.ppboard .st.judge{color:var(--judge)}

/* Belt and braces: whatever the nesting, the words below are never a rule
   stopping a release, and the audit re-runs on every build. */
.mockroot.ppboard .st.stop.who,.mockroot.ppboard .it .st.stop{color:var(--judge)}

.mockroot.ppboard .st.who{color:var(--judge);background:var(--judge-wash)}
.mockroot.ppboard .st.gap{color:var(--ink-2);background:var(--surface-3)}

/* ================= TEXT ON A WASH, IN BOTH THEMES =================
   mock.css flips every wash under `prefers-color-scheme:dark` — --flag-wash
   goes #FDEBF4 -> #2C0D1E — and the chips painted a hand-picked DARK hex on
   top of it. In a dark theme that is dark on dark, which is what the whole
   set of state chips measured at: "Cleared" 1.96, "Needs a person" 2.14,
   "Stops a release" 2.27.

   A colour used on a token ground has to be a token too, defined for both
   themes, or one of the two is always broken. These are that pair. */
.mockroot.ppboard{
  --on-flag-wash:#A4004F; --on-judge-wash:#584A75; --on-cleared-wash:#42561F;
  --on-beam-wash:#0B756F; --on-ink:var(--paper);
}
@media (prefers-color-scheme:dark){.mockroot.ppboard{
  --on-flag-wash:#FF8CC2; --on-judge-wash:#CBB9F3; --on-cleared-wash:#CDF177;
  --on-beam-wash:#6FEFE5;
}}
[data-theme="dark"] .mockroot.ppboard{
  --on-flag-wash:#FF8CC2; --on-judge-wash:#CBB9F3; --on-cleared-wash:#CDF177;
  --on-beam-wash:#6FEFE5;
}
[data-theme="light"] .mockroot.ppboard{
  --on-flag-wash:#A4004F; --on-judge-wash:#584A75; --on-cleared-wash:#42561F;
  --on-beam-wash:#0B756F;
}
.mockroot.ppboard .tg.stop,.mockroot.ppboard .st.stop.cp,
.mockroot.ppboard .st.stop.chip{color:var(--on-flag-wash)}
.mockroot.ppboard .tg.judge{color:var(--on-judge-wash)}
.mockroot.ppboard .tg.clear,.mockroot.ppboard .st.clear,.mockroot.ppboard .st.g{color:var(--on-cleared-wash)}

.mockroot.ppboard .tg.info,.tRules.ppboard .src .st.stop,.tRules.ppboard .src .tg.stop{color:var(--on-beam-wash)}
.mockroot.ppboard .cp:not(.on){color:var(--ink-2)}

/* ---- the piece on a canvas ------------------------------------------------
   Two boards, one shell: `.tPieceC` is what both share, `.vA` and `.vB` are
   the fork. The fork is what the permanent right-hand column carries, and it
   has a visible consequence — a column that carries the decision has to run to
   the bottom of the screen, so the strip stops short of it; a column that
   carries properties does not, so the strip runs under it, which is what the
   shipped Bench does.
   --------------------------------------------------------------------------- */
.tPieceC.ppboard .body{padding:0;display:grid;grid-template-rows:auto 1fr auto}
.tPieceC.ppboard.vA .body{grid-template-columns:1fr 400px}
.tPieceC.ppboard.vB .body{grid-template-columns:1fr 340px}
.tPieceC.ppboard.vA .cv-hd{grid-area:1/1/2/2} .tPieceC.ppboard.vB .cv-hd{grid-area:1/1/2/3}
.tPieceC.ppboard .cv-stage{grid-area:2/1/3/2}
.tPieceC.ppboard.vA .cv-strip{grid-area:3/1/4/2} .tPieceC.ppboard.vB .cv-strip{grid-area:3/1/4/3}
.tPieceC.ppboard.vA .pc-side{grid-area:1/2/4/3} .tPieceC.ppboard.vB .cv-dock{grid-area:2/2/3/3}

.tPieceC.ppboard .cv-hd{display:flex;align-items:center;gap:14px;padding:13px 26px;
                background:var(--surface);border-bottom:1px solid var(--line)}
.tPieceC.ppboard .cv-hd .acts2{margin-left:auto;display:flex;gap:9px;align-items:center}
.tPieceC.ppboard .cv-hd .gh,.tPieceC.ppboard .cv-hd .cta{padding:6px 11px;font-size:12.5px}

/* the bench: a recessed ground so the lit frame reads as the object on it */
.tPieceC.ppboard .cv-stage{background:var(--surface-3);position:relative;overflow:hidden;
                   display:flex;align-items:center;justify-content:center;gap:24px;padding:26px}

/* ---- the artwork. Content, not chrome: the kit's colours are literal and do
   not flip with the page theme, because the frame is what gets exported. ---- */
.mockroot.ppboard .cvf{background:#F7F5EF;color:#1A1712;position:relative;flex:none;
               display:flex;flex-direction:column;overflow:hidden}
.mockroot.ppboard .cvf.lg{width:372px;height:465px;padding:26px;border-radius:2px;
                  box-shadow:0 2px 5px rgba(23,21,28,.10),0 20px 46px rgba(23,21,28,.16)}
.mockroot.ppboard .cvf.sm{width:62px;height:78px;padding:5px;border-radius:2px;
                  box-shadow:0 1px 2px rgba(23,21,28,.14)}
.mockroot.ppboard .cvf .n{position:absolute;right:0;top:0;font-family:var(--mono);color:#6E6656}
.mockroot.ppboard .cvf.lg .n{right:26px;top:24px;font-size:11px}
.mockroot.ppboard .cvf.sm .n{right:5px;top:4px;font-size:4px}
/* `.h` IS A HEADLINE HERE AND A RESIZE HANDLE IN THE EDITOR.
   `bench.css:848` declares `.h` bare — 9x9, `--beam` ground, a white 1.5px
   border, `position:absolute`, `z-index:15` — with a `::after` that gives it a
   21px hit target. Measured on /app?preview: a `.cvf .h` carrying a headline
   drew as a 9x9 beam-green square at z-index 15. These are the values this
   board computes. */
.mockroot.ppboard .cvf .h{font-family:var(--serif);font-weight:600;letter-spacing:-.015em;display:block;
               position:static;inset:auto;width:auto;height:auto;background:none;border:0;
               border-radius:0;z-index:auto;pointer-events:auto;place-items:normal;cursor:auto}
.mockroot.ppboard .cvf .h::after{content:none}
.mockroot.ppboard .cvf.lg .h{font-size:31px;line-height:1.1;margin-top:64px}
.mockroot.ppboard .cvf.sm .h{font-size:6.5px;line-height:1.14;margin-top:11px}
.mockroot.ppboard .cvf .s{display:block;color:#5A5346}
.mockroot.ppboard .cvf.lg .s{font-size:14px;line-height:1.55;margin-top:20px;max-width:30ch}
.mockroot.ppboard .cvf.sm .s{font-size:3.6px;line-height:1.5;margin-top:4px}
.mockroot.ppboard .cvf .blk{background:#B02419;color:#F7F5EF;align-self:flex-start}
.mockroot.ppboard .cvf.lg .blk{padding:14px 18px;margin-top:56px}
.mockroot.ppboard .cvf.sm .blk{padding:3px 4px;margin-top:10px}
.mockroot.ppboard .cvf .blk .h{margin-top:0}
/* the squiggle on a brand ground: same mark, same meaning, the bright of the
   same magenta so it stays legible on the one frame that is not paper */
.mockroot.ppboard .cvf .blk .u-stop{text-decoration-color:var(--flag-bright)}
.mockroot.ppboard .cvf .f{margin-top:auto;display:flex;align-items:center;color:#3E3930}
.mockroot.ppboard .cvf.lg .f{gap:8px;font-size:12px}
.mockroot.ppboard .cvf.sm .f{gap:2px;font-size:3.4px}
.mockroot.ppboard .cvf .bm{background:#B02419;color:#fff;display:grid;place-items:center;font-weight:700}
.mockroot.ppboard .cvf.lg .bm{width:20px;height:20px;border-radius:4px;font-size:11px}
.mockroot.ppboard .cvf.sm .bm{width:6px;height:6px;border-radius:1.5px;font-size:3.4px}
.mockroot.ppboard .cvf.cap{background:#FBFAF6;border:1px solid #E2DCCF;box-shadow:none;display:flex;align-items:baseline;justify-content:space-between;gap:18px;margin-bottom:13px;flex-wrap:wrap}
.mockroot.ppboard .cvf.cap .n{position:static;font-size:3.6px;letter-spacing:.1em;margin-bottom:3px}
.mockroot.ppboard .cvf.cap .s{margin-top:0}

/* ---- the filmstrip. Scoped to this board and shared with nothing: it carries
   deck state and it is one screen's furniture (ds.py:487-490). ------------- */
.tPieceC.ppboard .cv-strip{background:var(--surface-2);border-top:1px solid var(--line);
                   display:flex;align-items:center;padding:14px 26px}
.tPieceC.ppboard .fs{display:flex;align-items:flex-end;gap:9px}
.tPieceC.ppboard .fs .cell{position:relative;display:flex;flex-direction:column;gap:4px}
.tPieceC.ppboard .fs .num{font-family:var(--sans);font-size:9px;color:var(--ink-3)}
.tPieceC.ppboard .fs .cell.on .num{color:var(--ink)}
.tPieceC.ppboard .fs .cell.on .cvf{outline:2px solid var(--beam);outline-offset:1px}
/* the bar is the frame's word count against the longest — the deck's rhythm,
   readable before anything is opened */
.tPieceC.ppboard .fs .bar{height:3px;border-radius:2px;background:var(--line-strong);display:block}
.tPieceC.ppboard .fs .bar u{display:block;height:3px;border-radius:2px;background:var(--ink-4)}
.tPieceC.ppboard .fs .cell.on .bar u{background:var(--ink)}
/* the mark on a frame carrying a finding that stops a release. It is the only
   reason frame 3 is legible from frame 1, and it is the signature magenta at
   the location of the finding, which is one of the three things it may mean. */
.tPieceC.ppboard .fs .pip{position:absolute;top:-5px;left:-4px;width:7px;height:7px;border-radius:50%;
                  background:var(--flag);z-index:1}
.tPieceC.ppboard .fs .add{width:62px;height:78px;border:1px dashed var(--line-strong);border-radius:2px;
                  display:grid;place-items:center;color:var(--ink-3);margin-bottom:11px}
.tPieceC.ppboard .fs .sep{width:1px;height:78px;background:var(--line);margin:0 7px 11px}
.tPieceC.ppboard .cv-facts{margin-left:auto;font-family:var(--sans);font-size:10.5px;
                   color:var(--ink-2)}

/* ---- the selection capsule. The verbs arrive at the object they change.
   Fixed graphite in both themes: it floats over artwork, and artwork does not
   flip with the page theme (src/editor/bench.css:44-60 declares its own
   palette for the same reason). ------------------------------------------- */
.tPieceC.ppboard .cap2{position:absolute;top:35px;left:50%;transform:translateX(-50%);
               background:#2B2833;color:#EFEDF3;border-radius:9px;padding:4px;z-index:2;
               display:flex;align-items:center;gap:2px;
               box-shadow:0 2px 5px rgba(0,0,0,.24),0 16px 38px rgba(0,0,0,.30)}
.tPieceC.ppboard .cap2 i{width:29px;height:29px;border-radius:6px;display:grid;place-items:center;
                 font-size:14px;font-style:normal}
.tPieceC.ppboard .cap2 i em{font-family:var(--serif);font-style:italic;font-size:15px}
.tPieceC.ppboard .cap2 i b{font-size:14px}
.tPieceC.ppboard .cap2 i.f{color:#FF6FB0;background:rgba(214,0,110,.30)}
.tPieceC.ppboard .cap2 .dv{width:1px;height:16px;background:rgba(239,237,243,.24);margin:0 4px}
.tPieceC.ppboard .cap2 .sz{font-family:var(--sans);font-size:11px;padding:0 4px;color:#CFCAD8}

/* ---- variant A: the column carries the findings and the decision --------- */
.tPieceC.ppboard .pc-side{border-left:1px solid var(--line);background:var(--surface-2);padding:20px;
                  display:flex;flex-direction:column;overflow:hidden}
.tPieceC.ppboard .pc-top{display:flex;flex-direction:column;gap:5px;padding-bottom:13px;
                 border-bottom:1px solid var(--line);margin-bottom:13px}
.tPieceC.ppboard .pc-top b{font-size:15px;color:var(--ink)}
.tPieceC.ppboard .pc-foot{margin-top:auto;padding-top:15px;border-top:1px solid var(--line)}
.tPieceC.ppboard .fnd2 p{font-size:13.5px;line-height:1.5;color:var(--ink);margin:9px 0 0}

/* ---- variant B: the same card, met in the margin instead of listed ------- */
.tPieceC.ppboard .cv-note{width:322px;flex:none}
.tPieceC.ppboard .cv-note .fnd2{margin-bottom:0;box-shadow:var(--shadow-3)}

/* ---- variant B: the column carries properties ---------------------------- */
.tPieceC.ppboard .cv-dock{border-left:1px solid var(--line);background:var(--surface-2);
                  display:flex;flex-direction:column;overflow:hidden}
.tPieceC.ppboard .cv-dock .dh{padding:17px 20px 15px;border-bottom:1px solid var(--line)}
.tPieceC.ppboard .cv-dock .dh b{display:block;font-family:var(--sans);font-size:10.5px;
                        color:var(--ink-2);margin-bottom:5px}
.tPieceC.ppboard .cv-dock .dh span{font-size:15px;color:var(--ink)}
.tPieceC.ppboard .cv-dock .dr{padding:14px 20px;border-bottom:1px solid var(--line-soft);
                      font-family:var(--sans);font-size:10.5px;
                      color:var(--ink-2);display:flex;align-items:center;gap:9px}
.tPieceC.ppboard .cv-dock .dr .ico{width:13px;height:13px;margin-left:auto}
.tPieceC.ppboard .cv-dock .dr .ico.r{transform:rotate(-90deg)}
.tPieceC.ppboard .cv-dock .dbody{padding:16px 20px;border-bottom:1px solid var(--line-soft)}
.tPieceC.ppboard .cv-dock .dl{display:block;font-size:11.5px;color:var(--ink-3);margin-bottom:7px}
.tPieceC.ppboard .cv-dock .drow{display:flex;gap:7px;margin-bottom:15px}
.tPieceC.ppboard .cv-dock .drow:last-child{margin-bottom:0}
.tPieceC.ppboard .cv-dock .fld{border:1px solid var(--line-strong);border-radius:var(--r-sm);
                       background:var(--surface);padding:7px 10px;font-size:12.5px;flex:1;
                       display:flex;align-items:center;gap:7px}
.tPieceC.ppboard .cv-dock .fld.c{justify-content:center}
.tPieceC.ppboard .cv-dock .fld.on{border-color:var(--beam);color:var(--beam)}
.tPieceC.ppboard .cv-dock .stp{border:1px solid var(--line-strong);border-radius:var(--r-sm);
                       background:var(--surface);width:32px;display:grid;place-items:center;
                       font-size:14px;color:var(--ink-2)}

/* the capsule is placed against the frame it floats over, not the bench */
.tPieceC.ppboard .cv-frame{position:relative;flex:none}
/* a chip in a header row reads across, not down */
.tPieceC.ppboard .cv-hd .tg{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;
                    border-radius:5px;font-size:12.5px}
.tPieceC.ppboard .cv-hd .tg .ico{width:14px;height:14px}
/* the rail has to hold the decision, so the cards are set tighter than the
   prose board's — three findings where prose had two */
.tPieceC.ppboard .fnd2{padding:13px 15px;margin-bottom:10px}
.tPieceC.ppboard .fnd2 q{font-size:14px;margin-top:8px}
.tPieceC.ppboard .fnd2 p{font-size:13.5px;line-height:1.5;color:var(--ink);margin:8px 0 0}
.tPieceC.ppboard .fnd2 .src3{margin-top:8px}
.tPieceC.ppboard .fnd2 .row2{margin-top:11px}
.tPieceC.ppboard .cv-facts{white-space:nowrap}

/* ---- variant A: three acts in the rail footer, one row -------------------- */
/* The footer carries three acts now, not two. Sign-off and release are the same
   ceremony in two modes (src/editor/BenchCeremony.tsx:51), so they stand
   together, and the hand-off stands with them. At the body control size they
   made two rows, and the second row pushed 65px of the rail past the bottom of
   a 900px window — measured, not guessed. At the size this board already uses
   for its header controls the three make one row inside 360px. Sign off keeps
   its lead by ground, not by size. */
.tPieceC.ppboard .pc-acts{display:flex;gap:9px;align-items:center}
.tPieceC.ppboard .pc-acts .cta,.tPieceC.ppboard .pc-acts .gh{padding:7px 11px;font-size:12.5px}

/* ---------------------------------------------------------------------------
   SETTINGS — the three sections set_rail() named and never drew.
   Appended, additive only. Nothing above is changed. Every colour here is a
   token so both themes are defined at once, which is the failure that has
   already happened on this project.
   --------------------------------------------------------------------------- */
.tSet.ppboard .set-fld{display:block;border:1px solid var(--line-strong);border-radius:var(--r-sm);
               background:var(--surface-2);padding:9px 12px;font-size:13.5px;color:var(--ink)}
.tSet.ppboard .set-hint{font-size:12.5px;line-height:1.55;color:var(--ink-2);margin:10px 0 0}
.tSet.ppboard .set-wr{display:grid;grid-template-columns:1fr 190px 140px;gap:16px;align-items:center;
              padding:13px 18px;border-bottom:1px solid var(--line-soft)}
.tSet.ppboard .set-sr{display:grid;grid-template-columns:34px 1fr auto;gap:14px;align-items:center;
              padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.tSet.ppboard .set-kr{display:grid;grid-template-columns:34px 1fr 150px 90px;gap:16px;align-items:center;
              padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.tSet.ppboard .set-wr:last-child,.tSet.ppboard .set-sr:last-child,.tSet.ppboard .set-kr:last-child{border-bottom:0}
/* A wash has to end where the word ends. `.tg` carries colour and ground in
   pitch.css and no box, which is right in a caption and wrong in a grid cell,
   where the cell stretches the ground across the column. */
.tSet.ppboard .tg{justify-self:start;padding:3px 8px;border-radius:3px}
/* Neither stop, judge nor cleared: a revoked key is a fact with no verdict in
   it. pitch.css defines the other four washes and not this one. */
.mockroot.ppboard .tg.mute{background:var(--surface-3);color:var(--ink-2)}
/* The Confirm. A fixed dark scrim in both themes — a scrim is a light level,
   not an ink, so it does not flip. The dialog is on --surface and carries its
   own border, which is what separates it from the scrim when the page under it
   is already dark. */
.tSet.ppboard .set-dim{position:absolute;inset:0;background:rgba(23,21,28,.46)}
.tSet.ppboard .set-md{position:absolute;left:50%;top:60%;transform:translate(-50%,-50%);width:470px;
              background:var(--surface);border:1px solid var(--line-strong);
              border-radius:var(--r-lg);box-shadow:0 30px 70px rgba(23,21,28,.5);padding:20px 22px}
.tSet.ppboard .set-md h4{margin:0 0 9px;font-size:17px;letter-spacing:-.01em;color:var(--ink)}
.tSet.ppboard .set-md p{margin:0;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
.tSet.ppboard .set-mf{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}

/* ---------------------------------------------------------------------------
   THE KEYS SCREEN'S OTHER THREE MOMENTS. Appended, additive only.
   No verdict colour anywhere in this block. What separates "no keys" from "the
   keys did not load" here is the shape of the block, not its hue — magenta on
   either would say a rule stopped a release, and neither did.
   --------------------------------------------------------------------------- */
/* Nothing issued. The block takes the space the list would have had, so the
   absence is on screen rather than implied by a gap. */
.tSet.ppboard .set-none{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
                margin-top:16px;padding:38px 22px;font-size:13.5px;line-height:1.6;
                color:var(--ink-2)}
/* Nothing read. Deeper ground, a rule down the side and a verb in it — three
   differences a reader registers before reading a word. */
.tSet.ppboard .set-un{background:var(--surface-3);border:1px solid var(--line-strong);
              border-left:3px solid var(--ink-2);border-radius:var(--r-lg);
              margin-top:16px;padding:18px 22px}
.tSet.ppboard .set-sec{background:var(--surface-2);border:1px solid var(--line-strong);
               border-radius:var(--r-lg);margin-top:16px;padding:18px 22px}
.tSet.ppboard .set-un b,.tSet.ppboard .set-sec b{display:block;font-size:14.5px;font-weight:500;
                                 color:var(--ink);margin:0 0 7px}
.tSet.ppboard .set-un p,.tSet.ppboard .set-sec p{margin:0;font-size:13.5px;line-height:1.6;
                                 color:var(--ink-2);max-width:80ch}
.tSet.ppboard .set-un .m{display:block;margin-top:11px}
.tSet.ppboard .set-acts{margin-top:14px}
.tSet.ppboard .set-kv{display:flex;gap:10px;align-items:center;margin-top:13px}
.tSet.ppboard .set-kv .set-fld{flex:1;background:var(--surface);font-family:var(--mono);font-size:12.5px;
                       letter-spacing:.02em;white-space:nowrap;overflow:hidden}
/* The value is drawn already selected, because the field selects itself on
   focus (ApiKeys.tsx:189-193) and that is the path a keyboard takes. --beam is
   emphasis with no alarm in it, which is what a selection is. */
.tSet.ppboard .set-sel{background:var(--beam-wash);color:var(--ink);border-radius:2px;padding:1px 3px}

/* ---------- MASTHEAD MARK ------------------------------------------------
   Down here, and not at `.sh` where it belongs, for one reason: a hundred
   comments across src/ cite `pitch.css:N` and `src/design/citations.test.ts`
   checks every one of them. This rule set is 30 lines longer than the disc it
   replaces, and inserting it in place moved fourteen citations off their
   lines — four of them in files this contract may not edit. Appended, the
   file above is byte-identical and every citation still lands. */
/* The masthead mark. Was a 20px conic-gradient disc standing in for a logo
   nobody had drawn; it is the owner's wordmark now, at the height the disc had,
   so the bar's rhythm is unchanged and only its width moves (20 -> 54.4).

   ONE ELEMENT, TWO PICTURES, AND THE SWAP IS IN `content`.
   The mark is black ink on transparent — 1.16:1 on the dark theme's --surface —
   so a dark ground needs the knockout. Two <img> tags with a display toggle
   would have been the obvious way and it is not taken: anything that reads the
   markup without applying CSS (jsdom, a static audit) sees both alts and the
   masthead's accessible name becomes "Inkstand Inkstand". `content` on a
   replaced element swaps what it draws and leaves one element with one alt.

   The two files are behind custom properties because this stylesheet is shared
   byte for byte with the board, and the board is opened over file:// where an
   absolute path resolves to the disk root. `pitch.py` redefines exactly these
   two, as data URIs, and nothing else about the mark differs between the two
   sides.

   The four blocks are the shape mock.css:735-760 records as the only one that
   wins: the media query is later in source than the base rule, and the two
   [data-theme] blocks outrank it at 0,4,0 — including the light one, which
   exists so a stamped light theme on an OS-dark machine does not get the
   knockout. A theme override appended at lower specificity is the bug that
   file is about.

   The box is stated rather than left to `width:auto`. 313/115 x 20 = 54.4, the
   mark's own ratio at the disc's height; `contain` letterboxes a mark of some
   other shape instead of stretching it. Stated because Chromium resolves
   `auto` against the element's intrinsic width, not the replaced content's:
   measured, the board drew 20x20 where the app drew 54x20. */
.mockroot.ppboard{--wm-l:url(/brand/inkstand-wordmark.png);
                  --wm-d:url(/brand/inkstand-wordmark-dark.png)}
.mockroot.ppboard .sh-m{height:20px;width:54.4px;flex:none;display:block;
                object-fit:contain;content:var(--wm-l)}
@media (prefers-color-scheme:dark){.mockroot.ppboard .sh-m{content:var(--wm-d)}}
[data-theme="dark"] .mockroot.ppboard .sh-m{content:var(--wm-d)}
[data-theme="light"] .mockroot.ppboard .sh-m{content:var(--wm-l)}

/* -------------------------------------------------------------------------
   COMPACT APP FRAME. The masthead becomes two deliberate rows: identity and
   actions first, section navigation second. The second row scrolls in its own
   axis, so every destination remains named and reachable without widening the
   document. Account navigation follows the same grammar above its content. */
.tSet.ppboard .brand-row{grid-template-columns:44px 1fr 130px 120px 100px 96px}

@media (max-width:640px){
  .mockroot.ppboard .sh{height:auto;min-height:100px;flex-wrap:wrap;gap:6px 10px;padding:8px 12px;align-content:center}
  .mockroot.ppboard .sh>a{display:flex;align-items:center;min-height:44px;flex:none}
  .mockroot.ppboard .sh-r{order:2;margin-left:auto;gap:6px;min-width:0}
  .mockroot.ppboard .sh-n{order:3;display:flex;flex:0 0 calc(100% + 24px);flex-wrap:wrap;margin:0 -12px -8px;padding:0 8px 6px}
  .mockroot.ppboard .sh-n a{min-height:44px;padding:8px 10px;white-space:nowrap;flex:1 1 auto;justify-content:center}
  .mockroot.ppboard .sh-new,.mockroot.ppboard .sh-b,.mockroot.ppboard .sh-r .av{min-height:44px}
  .mockroot.ppboard .sh-new{padding:8px 11px}
  .mockroot.ppboard .sh-b{max-width:152px;padding:8px 9px}
  .mockroot.ppboard .sh-b span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mockroot.ppboard .sh-r .av{width:44px;height:44px}

  .account-banner-shell{flex:none;padding:10px 12px 0}
  .account-banner-shell .bn{align-items:flex-start;flex-wrap:wrap;gap:9px}
  .account-banner-shell .bn>span:not(.ico){flex:1 1 calc(100% - 34px);min-width:220px;line-height:1.45}
  .account-banner-shell .bn>.b{min-height:44px;margin-left:34px!important}

  .tHome.ppboard .body{padding:20px 14px}
  .tHome.ppboard .home-head{display:flex;flex-direction:column;align-items:flex-start;gap:5px;margin-bottom:18px}
  .tHome.ppboard .grid{grid-template-columns:1fr;gap:12px}
  .tHome.ppboard .grid>*{grid-column:1/-1!important}
  .tHome.ppboard .mod a,.tHome.ppboard .mod button{min-height:44px;display:inline-flex;align-items:center}

  /* The core brand rooms keep the board's hierarchy on a phone, but exchange
     desktop columns for a single readable measure. Nothing in these routes
     earns document-wide sideways scrolling: every long title and provenance
     line is prose, so it wraps. Controls keep their visible compact styling
     while their target boxes take one full 44px beat. */
  .tMake.ppboard .body{display:flex;flex-direction:column;min-width:0}
  .tMake.ppboard .door{width:100%;min-width:0;padding:34px 18px;border-right:0;border-bottom:1px solid var(--line)}
  .tMake.ppboard .door:last-child{border-bottom:0}
  .tMake.ppboard .door h2{font-size:29px;overflow-wrap:anywhere}
  .tMake.ppboard .tpl{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
  .tMake.ppboard .tpl div{min-width:0}
  .tMake.ppboard :is(a,button){min-height:44px}

  .tWork.ppboard .bar2{padding:14px;align-items:stretch}
  .tWork.ppboard .bar2 .ans{flex:1 0 100%;margin-right:0!important;overflow-wrap:anywhere}
  .tWork.ppboard .srch{flex:1 0 100%!important;min-width:0;min-height:44px}
  .tWork.ppboard .srch input{min-width:0;min-height:44px}
  .tWork.ppboard .seg{width:100%;display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
  .tWork.ppboard .seg button,.tWork.ppboard .chip,.tWork.ppboard .bar2 .gh{min-width:44px;min-height:44px}
  .tWork.ppboard .scroll{overflow:visible;padding:14px}
  .tWork.ppboard .gal,.tWork.ppboard .kb{grid-template-columns:minmax(0,1fr);height:auto}
  .tWork.ppboard .it,.tWork.ppboard .it *,.tWork.ppboard .kc,.tWork.ppboard .kc *{min-width:0;overflow-wrap:anywhere}
  .tWork.ppboard .it .cap b{-webkit-line-clamp:unset;white-space:normal}
  .tWork.ppboard .lh{display:none}
  .tWork.ppboard .lr{grid-template-columns:44px minmax(0,1fr);gap:8px 10px;padding:12px 0}
  .tWork.ppboard .lr>:nth-child(n+3){grid-column:2;min-width:0;white-space:normal}

  .tRules.ppboard .body{display:flex;flex-direction:column;min-width:0}
  .tRules.ppboard .rail{display:flex;flex-wrap:wrap;width:100%;padding:6px 8px;border-right:0;border-bottom:1px solid var(--line)}
  .tRules.ppboard .rail a{flex:1 1 auto;justify-content:center;min-height:44px;padding:10px 12px}
  .tRules.ppboard .rail .g{display:flex;align-items:center;padding:0 8px}
  .tRules.ppboard .main{width:100%;min-width:0;padding:20px 14px;overflow:visible}
  .tRules.ppboard .main>*{max-width:100%;min-width:0}
  .tRules.ppboard .srch,.tRules.ppboard .srch input{width:100%;min-width:0;min-height:44px}
  .tRules.ppboard :is(.chip,.cp,.gh,.cta,select){min-height:44px}
  .tRules.ppboard .book{overflow:visible}
  .tRules.ppboard .rh{display:none}
  .tRules.ppboard .rw,.tRules.ppboard .book.pick .rw,.tRules.ppboard .src{display:grid;grid-template-columns:44px minmax(0,1fr);gap:8px 10px;padding:14px}
  .tRules.ppboard .rw>:not(:first-child),.tRules.ppboard .src>:not(:first-child){grid-column:2;min-width:0;white-space:normal;overflow-wrap:anywhere}
  .tRules.ppboard button:has(.ckx){min-width:44px;min-height:44px;display:grid;place-items:center}
  .tRules.ppboard .cov{grid-template-columns:minmax(0,1fr);gap:7px}
  .tRules.ppboard .sug,.tRules.ppboard .sug *{min-width:0;overflow-wrap:anywhere}

  .tRec.ppboard .body{display:flex;flex-direction:column;min-width:0}
  .tRec.ppboard .reg{width:100%;min-width:0;padding:20px 14px;overflow:visible}
  .tRec.ppboard .side{width:100%;min-width:0;padding:20px 14px;border-left:0;border-top:1px solid var(--line);overflow:visible}
  .tRec.ppboard .srch{flex:1 0 100%!important;min-width:0;min-height:44px}
  .tRec.ppboard .srch input{min-width:0;min-height:44px}
  .tRec.ppboard :is(button,a,select,input[type="date"]){min-height:44px}
  .tRec.ppboard button{min-width:44px}
  .tRec.ppboard .rr{grid-template-columns:minmax(0,1fr);gap:7px;padding:14px;text-align:left}
  .tRec.ppboard .rr>*{min-width:0;white-space:normal!important;overflow-wrap:anywhere}

  .tSet.ppboard .body{display:flex;flex-direction:column;min-width:0}
  .tSet.ppboard .rail{display:flex;align-items:stretch;flex-wrap:wrap;gap:2px;width:100%;padding:6px 8px;border-right:0;border-bottom:1px solid var(--line)}
  .tSet.ppboard .rail a{flex:1 1 auto;justify-content:center;min-height:44px;padding:10px 12px;white-space:nowrap}
  .tSet.ppboard .rail a.on{box-shadow:inset 0 -2px 0 var(--ink)}
  .tSet.ppboard .rail .g{flex:none;display:flex;align-items:center;padding:0 8px;white-space:nowrap}
  .tSet.ppboard .main{width:100%;min-width:0;padding:22px 14px;overflow:visible}
  .tSet.ppboard .card{max-width:100%}
  .tSet.ppboard .set-wr{grid-template-columns:minmax(0,1fr);gap:9px}
  .tSet.ppboard .set-kr{grid-template-columns:34px minmax(0,1fr);gap:10px;padding:14px}
  .tSet.ppboard .set-kr>:nth-child(n+3){grid-column:2}
  .tSet.ppboard .set-kr>:last-child{justify-self:start;min-height:44px}
  .tSet.ppboard .pr,.tSet.ppboard .bd{grid-template-columns:44px minmax(0,1fr);gap:10px;padding:14px}
  .tSet.ppboard .pr>:nth-child(n+3),.tSet.ppboard .bd>:nth-child(n+3){grid-column:2}
  .tSet.ppboard .ph{display:none}
  .tSet.ppboard .set-kv{align-items:stretch;flex-direction:column}
  .tSet.ppboard .set-kv .set-fld{width:100%;overflow-wrap:anywhere}
  .mockroot.ppboard .c-menu button{min-height:44px}
  .tSet.ppboard .tools :is(button,a,input),.tSet.ppboard .brand-row button{height:auto!important;min-height:44px!important}
  .tSet.ppboard .tools .srch{min-height:44px}
  .tSet.ppboard .set-fld{min-height:44px}
  .tSet.ppboard :is(.c-fld,.c-select){min-height:44px}
  .tSet.ppboard :is(.b,.c-btn,.cta,.gh){min-height:44px;display:inline-flex;align-items:center}
  .tSet.ppboard .srch{min-height:44px}
  .tSet.ppboard .srch input{min-height:44px}
  .tSet.ppboard .pr>*{min-width:0;overflow-wrap:anywhere}
}
/* A failed quote is a short recovery state, not an empty pricing canvas. Keep
   the message and its one available action together at reading width. */
.trial-wall .trial-failure {
  max-width: 38rem;
  margin-top: 1rem;
  padding: 1rem 1.125rem;
}

.trial-wall .trial-failure + .cta {
  margin-top: 0.875rem;
}

@media (max-width: 640px) {
  .trial-wall .cp,
  .trial-wall .cta,
  .trial-wall .set-fld,
  .trial-wall .set-sr:has(input[type='radio']) {
    min-height: 44px;
  }

  .trial-wall .trial-options {
    flex-wrap: wrap;
  }
}
/*
 * DIRECTION B — "THE INSTRUMENT". THE COPY STUDIO'S STYLESHEET.
 *
 * Source: `docs/superpowers/mockups/direction-b-instrument.html`, chosen by the
 * owner 2026-08-11 as the platform's design language.
 *
 * ---------------------------------------------------------------------------
 * THIS IS A COPY OF THE MOCK'S STYLE BLOCK, NOT AN INTERPRETATION
 * ---------------------------------------------------------------------------
 *
 * Same construction, and the same reasoning, as `src/design/mock.css`. The
 * rollout spec (`docs/superpowers/specs/2026-08-11-calm-system-rollout.md`
 * §4a) is explicit that five previous attempts failed because somebody started
 * at the existing component and edited toward the mock. The method that works
 * is to paste the mock in as code and reverse back into functionality — which
 * means this file is the mock's CSS, selector for selector and value for
 * value, and NOT a set of decisions about what the mock was getting at.
 *
 * ---------------------------------------------------------------------------
 * THE SUBSTITUTIONS, IN FULL
 * ---------------------------------------------------------------------------
 *
 * 1. EVERY COMPONENT RULE IS PREFIXED WITH `.instrument`.
 *    The mock is a standalone page and could own bare selectors. This app
 *    already loads `src/design/mock.css`, which owns `.ico`, `.prov` and
 *    `.sheet` — three names Direction B also uses. Prefixing is mechanical,
 *    preserves every selector's own text and every value, and is the smallest
 *    change that stops two stylesheets from fighting over three names. The
 *    markup is unchanged: the studio's root element is `.instrument`, exactly
 *    as it is in the mock.
 *
 *    AND PREFIXING ALONE IS NOT ENOUGH, which cost a screen check to learn. A
 *    prefixed rule only outranks the bare one for the properties it actually
 *    DECLARES. `mock.css`'s `.sheet` carries `background: var(--surface)` and a
 *    `border-right`; Direction B's `.sheet` declares neither, so the studio
 *    drew a white card with a rule down its side sitting on top of the cream
 *    paper — visible in a browser, invisible to every test. So each colliding
 *    selector below also neutralises whatever the other file sets on it, and
 *    those lines are marked `COLLISION`.
 *
 * 2. THE RATIONALE BAND AND DEMO STRIP ARE DROPPED.
 *    `.rationale`, `.lifts`, `.demo-strip`, `.demo-btn`, `.demo-hint` and the
 *    bare `kbd` reset styled the mock's explanatory header. §4a calls that
 *    "clearly-marked demo scaffolding" and says a mock is production material
 *    apart from it. Nothing else is dropped.
 *
 * 3. `.instrument` FILLS THE WINDOW INSTEAD OF SITTING IN A PAGE.
 *    The mock draws the studio as a 900px card centred on a grey page, because
 *    it is a picture of a product on a slide. In the product the instrument IS
 *    the screen. `max-width`, the outer margin, the shadow and the radius go;
 *    the height becomes 100%. Everything inside — the flex column, the plate,
 *    the paper, the console bar, the status plate — is untouched.
 *
 * 4. TOKENS ARE DECLARED ON `.instrument`, NOT ON `:root`.
 *    This said the opposite, on the reasoning that Direction B's palette is the
 *    platform's palette from here on (rollout §1) and so belongs where the rest
 *    of the platform can reach it. SCREEN-VERIFIED WRONG: `src/design/mock.css`
 *    already declares `--paper`, `--flag`, `--beam`, `--sans` and a dozen more
 *    on `.mockroot`, and its `--paper` is `#F4F3F6` — a flat app grey. The
 *    studio's paper measured `rgb(244, 243, 246)` in a browser, which is that
 *    value exactly: two systems were fighting over one name and the older one
 *    was winning.
 *
 *    Declaring them on `.instrument` settles it by proximity rather than by
 *    load order, which is the only version of this that cannot regress: a
 *    custom property resolves from the NEAREST ancestor that sets it, so
 *    everything inside the studio reads Direction B's palette whatever
 *    `mock.css` says about `:root`. When the rollout reaches Wave 2 and the
 *    platform's own surfaces convert, the block moves up and `mock.css`'s
 *    goes away — one system at a time, and never two claiming one token.
 *
 * 5. RULES THE PRODUCT NEEDS AND THE MOCK DID NOT DRAW ARE ADDED AT THE FOOT,
 *    under their own heading, built only from the primitives above. The mock
 *    drew no overlay panel, no outline rail, no agent pane and no pane divider
 *    — all of which the feature inventory requires. They are composed from the
 *    note, menu and plate vocabulary rather than invented, per the mock's own
 *    extensibility rule: paper, frame readout, or margin reading, and a feature
 *    needing a fourth voice does not ship.
 *
 * Rules the studio does not currently mount — the platform lens and the fold —
 * come along anyway, because leaving them in costs nothing and choosing between
 * them is how `mock.css` went wrong four times.
 */

/* ==========================================================================
   THE PALETTE
   ==========================================================================
   ONE SOURCE, AND IT FLIPS.

   What was here was thirty literal hexes: `--paper:#fbf8f2`, a graphite frame,
   a `--note-bg:#f4f2f6` for the margin. Every one of them was a constant, this
   file declared no `prefers-color-scheme` and no `[data-theme]` block, and the
   product stamps `data-theme` on `<html>` before first paint. So the studio was
   one fixed picture in both themes — and the parts of it drawn by tokens that
   DO flip (`ds.css`, the Tailwind ink scale the findings pane is written in)
   flipped underneath the parts that could not. That is how the findings pane's
   own heading came to be near-white text on `#f4f2f6`: 1.03:1, measured on
   `/app/b/…/copy/preview?preview` with `data-theme="dark"`.

   The cure is by construction rather than by a second palette. The studio root
   now carries `.mockroot ppboard tPiece` — the board's own wrapper — so
   `mock.css`'s tokens are declared on this element and already flip three ways
   (media, `[data-theme="dark"]`, `[data-theme="light"]`). Every name below is
   an ALIAS onto one of them. There is nothing left here for a theme to miss,
   because there is nothing left here with a colour in it.

   `--flag`, `--beam`, `--judge`, `--cleared`, `--sans`, `--serif` and `--mono`
   are NOT redeclared: `mock.css` owns those names on this same element, and an
   alias would be a second owner of a token whose whole value is that there is
   one. They arrive by inheritance and they flip with everything else.
   ========================================================================== */
.instrument {
  /* paper — the maker surface. `--surface` is the board's document ground:
     `.tPiece.ppboard .pc-doc` paints itself with it. */
  --paper: var(--surface);
  --p-ink: var(--ink);
  --p-ink-2: var(--ink-2);
  --p-hairline: var(--line);
  --p-meta: var(--ink-3);
  /* frame — the governance instrument.
     It was graphite in both themes, which is the Bench's argument (chrome
     beside ARTWORK must not flip, because artwork does not). A document is not
     artwork: the paper beside it is the theme, so the frame follows it. */
  --frame: var(--surface-2);
  --frame-2: var(--surface-3);
  --frame-line: var(--line);
  --readout: var(--ink-2);
  --readout-dim: var(--ink-3);
  --readout-hi: var(--ink);
  /* The softer squiggle: "needs a person" rather than "stops a release". Mixed
     from the signature toward the paper, so it is the same hue at less weight
     in whichever theme is on — the one thing a literal could not do. */
  --flag-soft: color-mix(in srgb, var(--flag) 55%, var(--surface));
  /* The live-act outline. `--beam` is the board's and flips; the frame variant
     is no longer a separate colour, it is the same one. */
  --beam-frame: var(--beam);
  /* the frame's voice entering the margin */
  --note-bg: var(--surface-2);
  --note-line: var(--line);

  /*
   * THE SHARED CHASSIS'S TOKENS, SUPPLIED BY THIS STUDIO.
   *
   * `.c-seltool` is owned by `calm.css` §8 and this studio wears it now rather
   * than a duplicate of it. Its tokens are declared on `.calm`, which is the
   * app shell's root — and the studio deliberately renders OUTSIDE that shell,
   * so every `var(--c-*)` in the chassis resolved to nothing: the capsule
   * rendered with no ground, no radius, no padding and no shadow, its icons
   * loose on the paper. Seen on screen, after the class was changed and before
   * this existed.
   *
   * These follow the frame — for the composer bar, the seam and everything
   * else in the studio that wears the chassis's names. The ONE surface they do
   * not govern is `.c-seltool` itself; see the block under this rule.
   */
  --c-frame: var(--frame);
  --c-frame-2: var(--frame-2);
  --c-frame-line: var(--frame-line);
  --c-serif: var(--serif);
  --c-mono: var(--mono);
  --c-readout: var(--readout);
  --c-readout-hi: var(--readout-hi);
  --c-readout-dim: var(--readout-dim);
  --c-beam: var(--beam);
  --c-beam-frame: var(--beam-frame);
  --c-paper: var(--surface);
  --c-card: var(--surface-2);
  --c-note-bg: var(--surface-2);
  --c-ink: var(--ink);
  --c-ink-2: var(--ink-2);
  --c-meta: var(--ink-3);
  --c-hairline: var(--line);
  --c-sans: var(--sans);
  --c-r-md: 9px;
  --c-gap-xs: 3px;
  --c-gap-sm: 6px;
  --c-gap-tight: 4px;
  --c-r: 9px;
  --c-r-sm: 6px;
  --c-gov-md: 9.5px;
  --c-gov-track: 0.13em;
  --c-e-seltool: var(--shadow-3);
}

/*
 * THE SELECTION CAPSULE IS AN INSTRUMENT, AND AN INSTRUMENT DOES NOT FLIP.
 *
 * Director's ruling, P6-b fix round 3 item 1. `.c-seltool` is a theme-invariant
 * graphite chassis — `#2B2833`, exactly as the Bench draws it — in BOTH themes
 * and BOTH studios, and `calm.css:787`'s `#C9C4D4` glyph ink is a literal
 * written FOR that chassis.
 *
 * What went wrong: `be728711` aliased `--c-frame: var(--frame)` above, so in
 * this studio the capsule's ground followed the theme while the ink on it —
 * owned by `calm.css`, which this contract may not edit — did not. Light theme
 * put `#C9C4D4` glyphs on a `#FAFAFC` capsule: **1.63:1**, measured with a
 * selection made. That is the ROE's named failure, a colour declared for one
 * theme, arriving by the back door of a token alias.
 *
 * The un-aliasing is scoped to the capsule rather than done at `.instrument`,
 * because the rest of the studio's chassis names are correct as aliases: the
 * composer bar is `--c-frame-2` on the paper (`studioComposer.css:11`) and it
 * MUST follow the theme — that is round 1 finding 5, and undoing it here would
 * trade one regression for another.
 *
 * Only the four colour tokens `.c-seltool` actually reads are pinned. The
 * literals are `calm.css:84-87` and `:110`, one for one; the shape tokens
 * (radius, padding, shadow, faces) stay on `.instrument` because a shape has
 * no theme.
 */
.instrument .c-seltool {
  --c-frame: #2b2833;
  --c-frame-2: #37333f;
  --c-frame-line: #443f4e;
  --c-readout-hi: #f4f2f8;
  /*
   * The finding verb's pink goes with them, and it is the same bug one rule
   * further down. `.instrument .seltool > button.why` paints with
   * `--flag-soft`, mixed toward `--surface`: pale in light, dark magenta in
   * dark. On a chassis that no longer flips, the dark mix is dark ink on a dark
   * ground — measured 1.45:1 when the chassis was pinned and this was not.
   *
   * So the capsule mixes toward the chassis's own light readout instead of
   * toward the page's surface: one pale pink on one graphite ground, in both
   * themes, which is what the rule's own comment has claimed all along.
   */
  --flag-soft: color-mix(in srgb, var(--flag) 55%, #f4f2f8);
}

.instrument * {
  box-sizing: border-box;
  min-width: 0;
}
.instrument svg {
  display: block;
}
.instrument .ico {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* ---------- tooltips: every icon explains itself on rollover ------------- */
.instrument [data-tip] {
  position: relative;
}
.instrument [data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--frame);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.3;
  padding: 5px 9px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease-out 0.3s;
  z-index: 40;
}
/*
 * A TRIGGER'S TOOLTIP GOES QUIET WHILE ITS OWN MENU IS OPEN.
 *
 * Seen on screen, twice. The selection bar's `···` drew "Role, comment, check"
 * across the bottom of the menu it had just opened, covering `Check the
 * document` and its hit area; the plate's `···` does the same to `Where this
 * came from`. The tooltip has already done its job by the time the menu is
 * there — it is naming a control the reader has now pressed — and two floating
 * surfaces at one point is the whole of §6.
 */
.instrument [data-tip]:hover::after,
.instrument [data-tip]:focus-visible::after {
  opacity: 1;
}
.instrument [data-tip].tip-below::after {
  bottom: auto;
  top: calc(100% + 9px);
}
.instrument [data-tip].tip-left::after {
  left: auto;
  right: 0;
  transform: none;
}

.instrument :focus-visible {
  outline: 2px solid var(--beam);
  outline-offset: 2px;
}
/* ONE MONO. `.tech` was `--font-mono`, which was then Martian Mono — so the
   studio rendered prose in a SECOND monospace face while its own mono was SF
   Mono on twenty-two other elements. The instrument's mono is the
   instrument's. Both tokens are SF Mono since 2026-09-16 and this rule still
   earns its place: it says which one owns the decision. */
.instrument .tech {
  font-family: var(--mono);
}
.instrument kbd {
  font-family: var(--mono);
  font-size: 11px;
  background: var(--surface-3);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--ink-2);
}

/* ---------- the instrument -------------------------------------------- */
/* SUBSTITUTION 3: the mock's centred card becomes the screen. */
.instrument {
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: var(--paper);
  color: var(--p-ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* top plate: title, the lens, one verb, one menu. Six labeled buttons die.
 *
 * THE PLATE SPEAKS ENGLISH. It carried `NORTHWIND DERMATOLOGY · VELTRIVA HCP
 * EMAIL` in 10.5px uppercase mono with .13em of tracking, and everything
 * inside it inherited that: the brand, the document's name, the version
 * chip's label. None of those is an identifier. They are names, and a name
 * set in a face reserved for things you spell out character by character is
 * the single loudest reason this product read as machine-made.
 *
 * Sans at 12.5, sentence case, no tracking. The tracking and the caps were
 * there to make small mono readable, so they leave with it; 12.5 is where the
 * sans lands for chrome of this density, and the plate's height does not
 * move. What still says "the record is speaking" here is the graphite ground
 * and the restraint, which is what the frame was always for. */
.instrument .plate {
  background: var(--frame);
  color: var(--readout);
  flex: none;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 0 14px 0 18px;
  min-height: 46px;
  font-family: var(--sans);
  font-size: 12.5px;
  position: relative;
  z-index: 30;
}

/* Icons keep their drawn size; their interactive box meets the touch-target
   floor across the header, rail, findings, comments, and assistant chrome. */
.instrument :is(.backbtn, .iconbtn, .lens button, .signoff, .findingrow button, .pact, .assistant-minimize) {
  min-width: 44px;
  min-height: 44px;
}
.instrument .plate .crumb,
.instrument .plate .rhs {
  transition: opacity 0.16s ease-out;
}
.instrument .plate .crumb {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: normal;
}
.instrument .plate .crumb > span:first-of-type {
  min-width: 0;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: anywhere;
}
/* ---------- the way out ------------------------------------------------
   `.crumb i` — a 7×7 teal square — used to be the first thing on this plate,
   in the position the Bench fills with its back control. A decoration standing
   in the affordance slot, and the only exit six items inside `···`. The owner
   read that as no exit existing, which is the correct reading of an invisible
   control.

   The Bench's `.backbtn` (`src/editor/bench.css`) is the same object and this
   studio does not load that stylesheet, so the geometry is restated here
   rather than reached for: 26×24, the frame's own hairline, the readout's
   colour. Somebody who has used one has used this.

   COMPUTED: `--readout` #A79FBC on `--frame` #2B2833 is 5.73:1 at rest;
   `--readout-hi` #F4F2F8 on `--frame-2` #37333F is 11.07:1 on hover. */
.instrument .plate .backbtn {
  background: none;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  color: var(--readout);
  width: 26px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  flex: none;
  transition: color 0.12s ease-out;
}
.instrument .plate .backbtn:hover,
.instrument .plate .backbtn:focus-visible {
  background: var(--frame-2);
  color: var(--readout-hi);
}
/* The frame goes quiet while somebody writes — but never the exit. Being
   unable to leave is what this control exists to answer, and a 0.34 opacity
   way out is most of the way back to not having one. */
.instrument.writing .plate .crumb .backbtn {
  opacity: 1;
}
.instrument .plate .crumb b {
  color: var(--readout-hi);
  font-weight: 600;
}
/* "Versions · Post · Carousel" — the label and the surfaces this post is read
   on. Names, so the chip loses the tracking the plate's mono needed and comes
   up to 11.5, which is the floor. */
.instrument .varchip {
  margin-left: 4px;
  padding: 2px;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  color: var(--readout);
  font-size: 11.5px;
  opacity: 0;
  transition: opacity 0.24s ease-out;
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
}
.instrument .varchip.on {
  opacity: 1;
}
.instrument .varchip .varlabel {
  color: var(--readout-dim);
  padding: 0 6px;
}
.instrument .plate .rhs {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  white-space: nowrap;
  position: relative;
}
.instrument .plate .live {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--beam-frame);
}
.instrument .plate .live i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--beam-frame);
  display: block;
}
/* THE LENS: which platform's fold the paper is read under */
.instrument .lens {
  display: flex;
  border: 1px solid var(--frame-line);
  border-radius: 6px;
  overflow: hidden;
}
.instrument .lens button {
  background: none;
  border: 0;
  color: var(--readout-dim);
  cursor: pointer;
  width: 30px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
}
.instrument .lens button.on {
  background: var(--frame-2);
  color: var(--beam-frame);
}
.instrument .lens button:hover:not(.on) {
  color: var(--readout-hi);
}
/*
 * DISABLED IS A COLOUR, AND THIS ONE WAS `opacity: .32`.
 *
 * The quiet state of the plate's own verb faded the label and the border at
 * the same rate, which is the failure the colour law names: the control stops
 * reading as a control before it stops reading as available. Measured on
 * `/app/b/…/copy/preview?preview`: `--readout-hi` at .32 over `--frame` is
 * 1.6:1 in light and 1.7:1 in dark — SIGN OFF was legible as a shape and not
 * as a word, in both. `shots/P6-b/copy-studio-{light,dark}-before.png`.
 *
 * The two states are two colours now: quiet is `--ink-3` on the frame's own
 * ground, live is `--beam` on the same ground with the beam's border. Nothing
 * is faded, so nothing is unreadable, and the difference between "you can
 * press this" and "not yet" is still the first thing the eye gets.
 *
 * AND THE QUIET BOX IS VISIBLE. The label was fixed and the border was not:
 * `--line` measured 1.23:1 light and 1.19:1 dark against the frame, which is
 * a box nobody can see. The quiet state is the state a REFUSED seat gets —
 * `aria-disabled`, focusable, with a reason to read — so it is a control a
 * person can land on, and a control with no visible boundary is the "nobody
 * could see it was a control" defect further down this file.
 *
 * `--line-strong` was the director's suggestion and it does not get there:
 * measured on the frame it is 1.46:1 light and 1.49:1 dark. `--line-control`
 * (`ds.css:964-970`) exists for this exact case — its own comment says the
 * lightness was moved "until it clears 3:1 on every ground a control here
 * sits on" — so that is what the quiet box takes.
 */
/* And the verb says "Sign off", not `SIGN OFF`. It is a control's label —
   what will happen when you press it — and the two states are already two
   colours, which is what the paragraph above is about. */
.instrument .signoff {
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 600;
  background: none;
  border: 1px solid var(--line-control);
  border-radius: 6px;
  color: var(--ink-3);
  padding: 6px 13px;
  opacity: 1;
  cursor: default;
  transition:
    border-color 0.24s ease-out,
    color 0.24s ease-out;
}
.instrument .signoff.earned {
  border-color: var(--beam-frame);
  color: var(--beam-frame);
  cursor: pointer;
}
.instrument .iconbtn {
  background: none;
  border: 0;
  color: var(--readout);
  cursor: pointer;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  padding: 0;
}
.instrument .iconbtn:hover {
  background: var(--frame-2);
  color: var(--readout-hi);
}
.instrument .iconbtn[aria-pressed='true'] {
  background: var(--frame-2);
  color: var(--beam-frame);
}
/* A colour, not a filter — the same shape as `.tools .tool:disabled` a few
   hundred lines below, which got this right and was never copied. An icon at
   30% opacity on this chrome is not dimmed, it is gone. */
.instrument .iconbtn:disabled {
  opacity: 1;
  color: var(--ink-3);
  cursor: default;
}
.instrument .iconbtn:disabled:hover {
  background: none;
  color: var(--readout);
}

/* menus: secondary commands live one level down, never on the surface */
.instrument .menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--surface);
  border: 1px solid var(--note-line);
  border-radius: 10px;
  padding: 6px;
  min-width: 220px;
  box-shadow:
    0 3px 8px rgba(23, 21, 28, 0.08),
    0 14px 40px rgba(23, 21, 28, 0.18);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.12s ease-out,
    visibility 0.12s;
  z-index: 35;
}
.instrument .menu.open {
  opacity: 1;
  visibility: visible;
}
.instrument .menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink);
  padding: 7px 9px;
  border-radius: 6px;
  cursor: pointer;
  letter-spacing: 0;
  text-transform: none;
}
.instrument .menu button:hover {
  background: var(--surface-3);
}
/*
 * A REFUSED ROW IS A COLOUR HERE TOO, and it was `opacity: .4` for `:disabled`
 * and NOTHING at all for `aria-disabled` — so the three writes in this menu
 * were pixel-identical to the three live rows beside them and said so only in
 * a `title`. `CopyStudio.tsx`'s note above the menu records finding that in a
 * screenshot and working around it with a mono `not your seat` on each row,
 * because "a stylesheet is not mine to edit". It is this pass's to edit.
 */
.instrument .menu button:disabled,
.instrument .menu button[aria-disabled='true'] {
  opacity: 1;
  color: var(--ink-3);
  cursor: not-allowed;
}
.instrument .menu button:disabled:hover,
.instrument .menu button[aria-disabled='true']:hover {
  background: none;
}
/* THE NAME IS A LEFTOVER, LIKE THE FACE WAS. What rides at the end of a menu
   row is "save first", "3 rules", "not your seat" — a condition, a count, a
   refusal. All English, all sans. Renaming it means editing `CopyStudio.tsx`
   and `BenchCapsule.tsx`; it is a name, not a face. */
.instrument .menu button .mono-aside {
  margin-left: auto;
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-3);
}
/* A menu's group label — "This text", "This frame". It names what the rows
   under it act on, which is a label and not a readout. */
.instrument .menu .glab {
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
  padding: 6px 9px 3px;
}
.instrument .menu hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 5px 4px;
}

/* writing state: the frame goes quiet — softly visible, never gone */
.instrument.writing .plate .crumb {
  opacity: 0.34;
}
.instrument.writing .plate .rhs {
  opacity: 0.22;
}
.instrument.writing .status .aux {
  opacity: 0.3;
}
.instrument.writing .status .sentence {
  opacity: 0.62;
}
.instrument.writing .composer {
  opacity: 0.4;
}
.instrument.writing .composer:hover,
.instrument.writing .composer:focus-within {
  opacity: 1;
}

/* paper — `.pc-doc` on the element. The ground is the board's
   (`pitch.css:527`) and is not painted twice; the scroll is stated on the
   element in `CopyStudio.tsx`, with the reason. */
.instrument .paper {
  flex: 1;
  position: relative;
}
/*
 * WHERE THE SHEET'S LEFT EDGE IS, stated once for everything that sits beside
 * it. NOT the mock's `margin: 0 auto` — see the margin-note block at the foot
 * of this file and `src/copy/noteGutter.ts`. Centred while centring can afford
 * the co-reader's gutter; capped the moment it cannot, so the margin comes out
 * of the empty left side rather than out of the reading. 620 measure, 284
 * gutter (62 offset + 210 note + 12 edge), 32 minimum left inset.
 *
 * Declared on the paper's children rather than on the paper, because `cqw`
 * resolves against the nearest ancestor container and `.paper` is the container.
 */
.instrument .paper > * {
  --sheet-left: max(32px, min((100cqw - 620px) / 2, 100cqw - 620px - 354px));
}
.instrument .sheet {
  max-width: 620px;
  margin: 0 auto 0 var(--sheet-left);
  padding: 60px 0 90px;
  position: relative;
  /* COLLISION: `mock.css` `.sheet` sets `background: var(--surface)` (white)
     and `border-right: 1px solid var(--line)`. Both were painting over the
     cream paper. */
  background: none;
  border-right: 0;
}
/* the instrument rail: one hairline where the co-reader's marks clip on.

   IT STARTS WHERE THE FIRST LINE STARTS, and only the screen knows where that
   is. `top` is measured from the sheet's BORDER box, so this 60px was a
   restatement of the 60px top padding above — one fact in two places, and the
   moment the padding changed for the board's beat the hairline stayed behind,
   34px low. The number now comes from the element, which is where the sheet's
   leading is decided (`Sheet.tsx`, `--sheet-rail-top`); the 60 is kept as the
   fallback so any sheet that does not state one is drawn as before. */
.instrument .sheet::after {
  content: '';
  position: absolute;
  top: var(--sheet-rail-top, 60px);
  bottom: 50px;
  left: calc(100% + 16px);
  width: 1px;
  background: var(--p-hairline);
}
.instrument .sheet h2 {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  margin: 0 0 40px;
}

/*
 * The document's name, on the paper, as a field.
 *
 * Inherits the `h2` metrics above it exactly, because it replaces that heading
 * and the sheet's vertical rhythm is measured in it. It is a field and has to
 * look like the title: no border and no fill at rest, so the paper reads as
 * paper, and a fill on hover and focus so the affordance is discoverable by
 * the ordinary means — moving the pointer over it.
 *
 * `width: 100%` and `display: block`: an input is inline-block and shrink-wraps
 * to its `size` attribute, so a full-width title would have been a 20-character
 * box with the name scrolling inside it — and the click target for the title
 * would have ended a third of the way across the page it titles.
 */
.instrument .sheet .papertitle {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.25;
  color: var(--p-ink);
  background: none;
  border: 0;
  border-radius: 6px;
  margin: 0 0 40px;
  padding: 2px 6px;
  /* Pulled left by its own padding so the title's first letter sits on the
     same optical margin as the paragraphs under it. A title indented 6px from
     its own body text is the kind of misalignment nobody names and everybody
     sees. */
  margin-left: -6px;
}
.instrument .sheet .papertitle:hover,
.instrument .sheet .papertitle:focus {
  background: var(--frame-2);
  outline: none;
}
.instrument .sheet .papertitle::placeholder {
  color: var(--p-ink);
  opacity: 0.32;
}
.instrument .pline {
  position: relative;
  margin: 0 0 48px;
} /* 1.5lh beat between blocks */
/* THE PROSE IS THE BOARD'S: 18px / 1.8 / 46ch, `pitch.css:533`. What was here
   was 19px on a 32px leading and the whole 620 measure, which is a second
   opinion about the one thing `piece()` is a picture of. The two role variants
   below are not — a hook and a quiet note are roles the board has no fixture
   for, and they keep their own metrics. */
/* HOOK PRIMACY: on social, the first line is the whole game */
.instrument .pline.hook p {
  font-size: 22px;
  line-height: 34px;
  font-weight: 500;
  letter-spacing: -0.012em;
}
.instrument .pline.quietnote p {
  font-size: 15px;
  line-height: 26px;
  color: var(--p-ink-2);
}
.instrument .sheet [contenteditable] {
  outline: none;
  caret-color: var(--p-ink);
}
.instrument ::selection {
  background: var(--beam-wash);
}

/* THE FOLD: where the platform truncates the caption — a fact of the paper,
   drawn as one quiet dashed hairline with its reading in the margin */
.instrument .fold {
  position: absolute;
  left: 0;
  width: 100%;
  border-top: 1px dashed var(--line-strong);
  pointer-events: none;
  transition: top 0.16s ease-out;
}
/* The fold's reading in the margin: "LinkedIn · see more" over "linkedin ·
   line 3". A platform's name and where the cut falls — metadata, so it is
   sans and sentence case, at 11 where the gutter is 160px wide and the tag
   still wraps at the middot. */
.instrument .fold .ftag {
  position: absolute;
  left: calc(100% + 26px);
  top: -7px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--p-meta);
  white-space: nowrap;
  line-height: 1.5;
}
.instrument .fold .ftag em {
  display: block;
  font-style: normal;
  opacity: 0.6;
}

/* THE SIGNATURE MARK.
   SEVERITY'S COLOUR IS NOT DECLARED HERE ANY MORE. The board draws the two
   squiggles itself: `.u-stop` (`pitch.css:640`), and
   `.u-judge` (`pitch.css:642`). The
   mark wears those classes, so `.mk.stop.on` (`--flag`) and `.mk.hold.on`
   (`--flag-soft`, 55% of the signature magenta on a judgement, which is the
   colour law's own defect) are gone rather than restated. What is left is the
   base every mark shares and the pointer; the second axis keeps its shape rule
   further down this file. */
.instrument .mk {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  transition: text-decoration-color 0.24s ease-out;
}

/* margin marks: a short rule in the gutter, one gesture with the squiggle */
.instrument .mmark {
  position: absolute;
  left: calc(100% + 26px);
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.24s ease-out;
}
.instrument .mmark::before {
  content: '';
  position: absolute;
  left: 10px;
  top: 21px;
  width: 24px;
  border-top: 2px solid var(--flag);
}
/* A judgement's dash is `--judge`, which is the law: `--flag` means a finding
   that stops a release, its squiggle and the count of those, and a judgement is
   none of the three. It was `--flag-soft` — the signature magenta at 55% — so
   the gutter said "stop, a bit" beside a rule waiting for a person. */
.instrument .mmark.hold::before {
  border-top-color: var(--judge);
}
.instrument .mmark.on {
  opacity: 1;
}
.instrument .mmark:focus-visible {
  outline: 2px solid var(--beam);
  outline-offset: 3px;
  border-radius: 2px;
}

/* A comment is context, not a release finding: a quiet pin on the same gutter,
   in beam rather than flag. Only current anchors render this control. */
.instrument .commentmark {
  position: absolute;
  /* Comments and findings are different things and must also be different hit
     targets. The finding dash owns the outer gutter lane at +26px; the comment
     pin stays beside the paper edge, leaving a real gap between their boxes. */
  left: calc(100% - 20px);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--beam);
  cursor: pointer;
  font-size: 8px;
  z-index: 2;
}
.instrument .commentmark::before {
  content: '';
  position: absolute;
  inset: 11px;
  border: 1px solid var(--note-line);
  border-radius: 999px;
  background: var(--paper);
}
.instrument .commentmark > span {
  position: relative;
  z-index: 1;
}
.instrument .commentmark:hover,
.instrument .commentmark:focus-visible {
  outline: none;
}
.instrument .commentmark:hover::before,
.instrument .commentmark:focus-visible::before {
  border-color: var(--beam);
}

/* margin note: the frame's voice, beside the line, never over the words */
.instrument .note {
  position: absolute;
  left: calc(100% + 74px);
  width: clamp(210px, calc((100vw - 620px) / 2 - 92px), 300px);
  background: var(--note-bg);
  border: 1px solid var(--note-line);
  border-radius: 9px;
  padding: 13px 15px 12px;
  box-shadow:
    0 1px 2px rgba(23, 21, 28, 0.05),
    0 10px 30px rgba(23, 21, 28, 0.09);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.16s ease-out,
    visibility 0.16s;
  z-index: 6;
}
.instrument .note.open {
  opacity: 1;
  visibility: visible;
}
.instrument .note .prov {
  /* COLLISION: `mock.css` `.prov` sets `margin-top: 9px` and
     `flex-wrap: wrap`, neither of which this row wants. */
  margin-top: 0;
  flex-wrap: nowrap;
  /* What the note's provenance line actually says: "Matched the rule's own
     words", "A reading, held until sign-off", "A rule reaches this and
     nothing has read it" (`Sheet.tsx:182`). Three sentences about how much to
     trust the finding — the opposite of a thing you spell out. Sans at 11.5,
     and the tracking goes with the caps. */
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-3);
  margin-bottom: 7px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.instrument .note .prov u {
  text-decoration: none;
  color: inherit;
}
.instrument .note .prov .x {
  background: none;
  border: 0;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 4px;
}
.instrument .note h4 {
  margin: 0 0 5px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.instrument .note h4.stop {
  color: var(--flag);
}
.instrument .note .rule {
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0 0 9px;
}
.instrument .note .acts {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  border-top: 1px solid var(--note-line);
  padding-top: 9px;
  margin-top: 2px;
}
.instrument .note .act {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--note-line);
  border-radius: 6px;
  padding: 5px 10px;
  cursor: pointer;
}
.instrument .note .act:hover {
  border-color: var(--line-strong);
}
.instrument .note .act span {
  font-family: var(--mono);
  font-size: 9.5px;
  color: var(--ink-3);
  font-weight: 500;
  margin-left: 5px;
}
/* "No wording supplied — a person decides", beside the acts it stands in for.
   A sentence. */
.instrument .note .nowording {
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-3);
  align-self: center;
}

/* SELECTION IS THE PRIMARY VERB — the instrument hands you tools.
   Icons only; every one explains itself on rollover.

   THE CHASSIS IS NOT DEFINED HERE. It is `.c-seltool`, owned by `calm.css` §8,
   and this file carried a byte-duplicate of it: same background, same radius,
   same padding, same shadow, same 29px buttons, two owners. The drift had
   already started — the mock's `font-family: var(--serif); font-size: 14px`
   survived here and had been dropped from `calm.css` (it is back there now,
   where the B and I glyphs are letterforms and need it), and this studio said
   `.sep` where the Bench says `.c-sep` for the same 1×16px rule.

   The owner's law is one chassis, studio-specific cargo, so that a person
   cannot tell which studio they are in by looking at the hero surface. What is
   left below is genuinely this studio's cargo: where the capsule is PLACED, and
   which way its menu flips. */
.instrument .seltool {
  /* `Range#getBoundingClientRect()` is viewport-relative, so the capsule must
     share that coordinate system. Absolute positioning applied the studio's
     own offset a second time and could leave a real selected-text action
     outside the visible work area even though jsdom still found its DOM. */
  position: fixed;
  /* `bench.css` is loaded globally and its canvas-only `.seltool` starts at
     `display:none`. The studio-qualified rule must restore the shared chassis;
     opacity alone cannot reveal an element removed from layout. */
  /* `bench.css` is global and its canvas-only `.seltool` deliberately uses
     `display: none !important` until the Bench has a selection. This studio's
     qualified rule must beat that declaration; otherwise the selection state
     and actions exist in the DOM but are literally never painted. */
  display: flex !important;
  max-width: calc(100vw - 24px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.12s ease-out,
    visibility 0.12s;
  transform: translateX(-50%);
}
.instrument .seltool.open {
  opacity: 1;
  visibility: visible;
}
/* The signature's pink on the finding verb, and nothing else about the button
   changes — the Bench's `.why` does exactly this. The full `#D6006E` is 2.81:1
   on graphite: it fails as a foreground, so the softer signature carries it.
   MEASURED on the running capsule, with `--flag-soft` pinned to the chassis
   above: `rgb(228,109,172)` light and `rgb(250,134,190)` dark on `#2B2833` —
   4.86:1 and 6.35:1. The button draws only when the selection contains a
   finding's excerpt (`CopyStudio.tsx:2310`), which the preview fixture does not
   produce, so those two are read off an injected `.why`, not off a screenshot. */
.instrument .seltool > button.why {
  color: var(--flag-soft);
}
.instrument .seltool > button.named-action {
  width: auto;
  min-width: 44px;
  padding-inline: 10px;
  gap: 6px;
  font-family: var(--sans);
  font-size: 12px;
  white-space: nowrap;
}
.instrument .seltool .menu {
  right: auto;
  left: 50%;
  transform: translateX(-50%);
}

.instrument .composer {
  position: relative;
  width: min(620px, 100%);
  transition: opacity 0.16s ease-out;
}
.instrument .console-disclosure__head,
.instrument .console-disclosure__reopen {
  margin: 0 6px;
  min-height: 36px;
  border: 1px solid var(--note-line);
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
  background: var(--note-bg);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 12px;
}
.instrument .console-disclosure__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px 0 13px;
}
.instrument .console-disclosure__head span {
  display: flex;
  gap: 2px;
}
.instrument .console-disclosure__head button,
.instrument .console-disclosure__reopen {
  min-height: 36px;
  padding: 0 9px;
}
.instrument .console-disclosure__head button:hover,
.instrument .console-disclosure__reopen:hover {
  color: var(--ink);
}
.instrument .console-disclosure__reopen {
  width: calc(100% - 12px);
  border-bottom: 1px solid var(--note-line);
  border-radius: 10px;
  text-align: left;
}
.instrument .console-conversation {
  max-height: min(28vh, 240px);
  overflow-y: auto;
  margin: 0 6px 10px;
  border: 1px solid var(--note-line);
  border-radius: 10px;
  background: var(--note-bg);
}
.instrument .console-disclosure[data-state='open'] .console-conversation {
  border-radius: 0 0 10px 10px;
}
.instrument .console-conversation:not(:has(.mt-6, [role='status'], [role='alert'])) {
  display: none;
}
.instrument .console-conversation .flow {
  padding: 12px 14px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
}
.instrument .composer .resp {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 6px;
  right: 6px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 13px;
  background: var(--note-bg);
  border: 1px solid var(--note-line);
  border-radius: 9px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-2);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.16s ease-out,
    visibility 0.16s;
}
.instrument .composer .resp.open {
  opacity: 1;
  visibility: visible;
}
.instrument .composer .resp .ico {
  margin-top: 2px;
  color: var(--beam);
}
/*
 * A REFUSAL CARRIES ITS OWN ANSWER.
 *
 * The same note the co-reader replies in, with the offer attached, because the
 * refusal and the thing you do about it are one thought. `flex-shrink: 0` and
 * `white-space: nowrap` because without them "Send the first 10" broke over two
 * lines against the sentence and read as two controls rather than one.
 *
 * `margin-left: auto` on the first of them pushes the pair to the trailing edge
 * and lets the sentence keep the width it needs.
 */
.instrument .composer .resp > span {
  flex: 1 1 auto;
}
.instrument .composer .resp button {
  flex: 0 0 auto;
  white-space: nowrap;
  align-self: center;
  min-width: 44px;
  min-height: 44px;
  padding: 4px 10px;
  border-radius: 6px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.instrument .composer .resp .resp-do {
  border: 1px solid var(--ink, #221f2b);
  background: var(--ink, #221f2b);
  color: var(--note-bg, #fff);
}
.instrument .composer .resp .resp-no {
  border: 1px solid var(--note-line);
  background: transparent;
  color: inherit;
}
.instrument .capsule {
  display: flex;
  align-items: center;
  gap: 11px;
  background: var(--surface);
  border: 1px solid var(--note-line);
  border-radius: 999px;
  padding: 9px 9px 9px 17px;
  box-shadow:
    0 2px 5px rgba(23, 21, 28, 0.07),
    0 10px 34px rgba(23, 21, 28, 0.12);
}
.instrument .capsule:focus-within {
  border-color: var(--line-strong);
}
.instrument .capsule .nib {
  color: var(--beam);
}
.instrument .capsule input {
  flex: 1;
  border: 0;
  background: none;
  outline: none;
  font-family: var(--sans);
  font-size: 14.5px;
  color: var(--p-ink);
}
.instrument .capsule input::placeholder {
  color: var(--p-meta);
}
.instrument .capsule .khint {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--p-meta);
  flex: none;
}
.instrument .capsule .send {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 0;
  background: var(--frame);
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
}
.instrument .capsule .send:hover {
  background: var(--frame-2);
}

/* bottom plate — the status readout. The co-reader's mouth: one grammatical
   sentence — "One thing stops a release; one more wants a look." It was mono
   "because the instrument is speaking", and that argument died on 2026-09-16:
   a sentence is a sentence whoever is saying it, and the instrument is
   recognised by its graphite ground, not by a typewriter. Sans at 12, the
   size it already was, sentence case as it already was. */
.instrument .status {
  background: var(--frame);
  color: var(--readout);
  flex: none;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 18px;
  font-family: var(--sans);
  font-size: 12px;
  position: relative;
  z-index: 12;
}
.instrument .status .sentence {
  display: flex;
  align-items: center;
  gap: 9px;
  letter-spacing: 0.01em;
  color: var(--ink-2);
  transition: opacity 0.16s ease-out;
}
.instrument .status .sentence i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--beam-frame);
  display: block;
  flex: none;
  opacity: 0;
  transition: opacity 0.24s ease-out;
}
.instrument .status .sentence.reading i {
  opacity: 1;
  animation: instrument-breathe 1.2s ease-in-out infinite;
}
@keyframes instrument-breathe {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}
.instrument .status .sentence.clear {
  color: var(--beam-frame);
}
/* LOWER CASE, because the board's is. `ds.py`'s status line ends
   `68 words · saved · 14 rules in force` (`STUDIO1`, `ds.css:615`) and this
   read `68 WORDS SAVED 15 RULES IN FORCE`. The separators are in the markup,
   where the board puts them too.

   `text-transform: none` and not a deleted declaration, and that is a
   measurement rather than a preference: an unscoped `.status .aux`
   (`bench.css:1786`) reaches this studio whenever the Bench's chunk is in the
   graph, and it declared `uppercase` — deleting the declaration here left the
   plate upper case on the screen. That rule says `none` itself now, so the
   leak carries the right answer; closing it is still P6-a's. */
.instrument .status .aux {
  margin-left: auto;
  /* 11 and no tracking. It inherits the plate's sans now, and .11em was the
     gap uppercase mono needed to stay apart — on a sans in sentence case it
     is a lisp. */
  font-size: 11px;
  text-transform: none;
  color: var(--readout-dim);
  white-space: nowrap;
  transition: opacity 0.16s ease-out;
}

/* ==========================================================================
   SUBSTITUTION 5 — WHAT THE MOCK DID NOT DRAW
   ==========================================================================
   Built from the vocabulary above and nothing else. Each of these is required
   by PART 1 of `docs/superpowers/audits/2026-08-11-studios-feature-inventory.md`
   and speaks in one of the mock's three voices: paper, frame readout, or
   margin reading.
   ========================================================================== */

/* ---------- the frame's own furniture -----------------------------------
   The skip link, the editable title in the crumb, the landmark that holds the
   work, and the two states the studio has before a document arrives. */

/* 23 focusable stops stand between the top of this screen and the first
   paragraph. Hidden until focused; the target takes focus itself. */
.instrument .skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 60;
}
.instrument .skip:focus {
  left: 12px;
  top: 8px;
  background: var(--frame);
  color: var(--readout-hi);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 7px;
  text-decoration: none;
}

/* The plate states the document's identity and no longer edits it. The field
   moved to the paper — see `.papertitle` — because a name in the chrome after
   a middot reads as the tail of a breadcrumb, and nobody types into a
   breadcrumb. It was 11px uppercase mono when that was found, which made it
   worse; it is the plate's sans now, and the field still belongs on the
   paper. */
.instrument .plate .crumb .titlelabel {
  color: var(--readout-hi);
  max-width: none;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

.instrument .mainpane {
  flex: 1;
  min-height: 0;
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  outline: none;
}

/* One governed post, several surface-specific readings. The active surface is
   a filled readout rather than a louder colour: it is identity, not status. */
.instrument .varchip a {
  color: inherit;
  text-decoration: none;
  padding: 4px 7px;
  border-radius: 4px;
  line-height: 1;
}
.instrument .varchip a.on {
  color: var(--readout-hi);
  font-weight: 600;
  background: var(--frame-2);
}
.instrument .varchip a:hover,
.instrument .varchip a:focus-visible {
  color: var(--readout-hi);
  background: var(--frame-2);
}

/* The status plate's readouts are buttons — "house rules · 4" is a claim, and
   the coverage panel is where it is substantiated. */
.instrument .aux {
  display: flex;
  align-items: center;
  gap: 14px;
}
.instrument .auxbtn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
}
.instrument .auxbtn:hover {
  color: var(--readout-hi);
}

.instrument .menulink {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink);
  padding: 7px 9px;
  border-radius: 6px;
  text-decoration: none;
  letter-spacing: 0;
  text-transform: none;
}
.instrument .menulink:hover {
  background: var(--surface-3);
}

/*
 * THE NOTICES LIVE IN THE MARGIN, NOT IN A BAND ABOVE THE WORDS.
 *
 * They were a full-width stack across the top of the paper, and that is the
 * placement Direction B's whole composition exists to avoid: the mock never
 * puts anything between the top of the sheet and the first line, because the
 * first line is the thing the surface is for. Using the note's MATERIAL is not
 * the same as being in the note's PLACE — the material was right and the
 * position was a fourth voice appearing the moment somebody edits.
 *
 * So they clip onto the same rail the findings clip onto, in the same gutter,
 * at the top of the sheet. Below the width where that gutter exists they fall
 * back to the measure, above the words, which is the only place left — the same
 * fallback the margin note takes.
 */
.instrument .notices {
  position: absolute;
  top: 60px;
  /* The same gutter the margin note takes, off the same edge: the sheet's left
     plus its 620 measure plus the note's 62 offset. It used to assume a CENTRED
     sheet — `calc(50% + 372px)` — which stopped being true when the gutter
     started being reserved, and would have parked every notice inside the
     words. One expression, `--sheet-left`, consumed by both. */
  left: calc(var(--sheet-left) + 682px);
  width: clamp(280px, calc(50cqw - 384px), 300px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 5;
}
@container (max-width: 1005px) {
  .instrument .notices {
    position: static;
    width: auto;
    max-width: 620px;
    margin: 0 auto;
    padding: 22px 0 0;
  }
}

/* Loading, and a failed read. The frame is drawn in both — a work surface that
   strands somebody on a failure with nothing to click is worse than one that
   never opened. */
.instrument .statepane {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 60px 24px;
}
.instrument .statepane > * {
  max-width: 620px;
  margin: 0 auto;
}
.instrument .skeleton {
  display: grid;
  gap: 14px;
  margin: 18px auto 0;
}
.instrument .skeleton span {
  display: block;
  height: 13px;
  border-radius: 4px;
  background: var(--note-line);
  opacity: 0.7;
}
.instrument .skeleton span:nth-child(2) {
  width: 92%;
}
.instrument .skeleton span:nth-child(4) {
  width: 78%;
}
.instrument .skeleton span:nth-child(5) {
  width: 46%;
}

.instrument .sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- `.live`, and the rule that was hiding it --------------------
 *
 * P6-a's review asked for `bench.css`'s unscoped `.live` to be MOVED here,
 * on the reading that it is this studio's announcer. It is not. Looked at on
 * screen (`shots/P6-b/r2-studio-{light,dark}-before.png`, the plate's right
 * end) and then measured: the only element in the product carrying `.live` is
 * the plate's LIVE CHIP in `CopyStudio.tsx` — a visible pip and a word saying
 * whether the check is running — and `bench.css` was clipping it to 1×1.
 * Nothing in `src/editor` carries the class at all.
 *
 * So the announcer that rule was written for does not exist, and copying it
 * here would reproduce the defect under a new address. What is stated instead
 * is the only fact that was ever in dispute: on this screen `.live` is seen,
 * not heard. `.instrument .plate .live` already declares the chip's layout
 * (`:432`) and its pip (`:438`) and hides it under 900px (`:2396`) — all of it
 * dead while the element measured one pixel square.
 *
 * DELETE THIS BLOCK when `bench.css`'s `.live` goes with P6-a. It has no job
 * except to outrank a rule that is leaving, and it says so here rather than
 * being left for somebody to find. */
.instrument .plate .live {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
}

/* ---------- the second axis on a mark ----------------------------------
   The mock's fixture only ever had to say how BADLY a finding is wanted, so
   `.mk.stop` and `.mk.hold` carry severity in colour and nothing carries kind.
   A document needs the other axis too: a pattern code matched is settled, and
   a rule that merely reaches these words is not. Drawing a model's opinion
   with the geometry of a matched pattern is the worst mark this product can
   make (`src/copy/marks.ts` argues the case). So severity keeps the mock's
   colour and kind takes shape.

   SHAPE, AND NOT A DIFFERENT DRAWING. This turned the underline OFF and drew
   two 1.5px `var(--beam)` hairlines at the ends of the phrase instead. Three
   things were wrong with that and they compounded:

     `--beam` is `#0B756F`, a dark teal — and it is this surface's CARET colour,
     the same value that rules the gutter beside the block being written in. A
     release-blocking finding was therefore drawn in the colour of "you are
     typing here", and `.mk.stop.on`'s `var(--flag)` had nothing left to paint.

     1.5px verticals at the ends of a phrase ARE a text caret, visually. The
     owner's paragraph contained a real one, which is how the mark did not read
     as faint — it read as absent.

     `opacity` fades the WHOLE mark, and this mark is on live text, so the
     entrance took the words with it. The severity fade is on
     `text-decoration-color` for exactly that reason.

   So the second axis keeps its own geometry and gives up its own colour: a
   DASHED underline against the wavy one, 2px so it survives a 19px serif, and
   the colour arrives from the board's `.u-stop` / `.u-judge` as it does for a
   pattern match. Dashed against wavy is a distinction that survives being
   printed, being colour-blind and being small; teal against magenta was not.
   `src/copy/markShape.test.ts` holds the law and the reasoning. */
.instrument .mk[data-kind='judge'] {
  text-decoration-style: dashed;
  text-decoration-thickness: 2px;
  /* Further off the baseline than the wavy mark, because a dash sits where a
     descender does and 4px put it through the tail of a `p`. */
  text-underline-offset: 5px;
}
.instrument .mk {
  cursor: pointer;
}

/* Provenance as a glyph rather than a panel: findable when wanted, invisible
   while reading. Mono, because a rule identity is the record speaking. */
.instrument .mark-cite {
  font-family: var(--mono);
  font-size: 9px;
  vertical-align: super;
  color: var(--p-meta);
  padding: 0 1px;
  cursor: pointer;
  user-select: none;
}
.instrument .mark-cite:hover {
  color: var(--beam);
}

/* THE GUTTER TAG IS GONE. It drew `02 · notes` beside every block, which was a
   second mark for "this block is active" beside the margin bar below, and a
   third thing in a gutter that already carries the finding marks. Position is
   in the outline rail, which lists the blocks and is what a list is for; the
   role is on the left rail with a handle that states the current answer and
   every alternative's rule count beside it. */

/* The block you are writing in, marked in the margin rather than boxed.
   The mock's paper has no focus ring on the words because its fixture is one
   block; a document needs to say which block has the caret without drawing on
   the sentence. */
.instrument .pline p[contenteditable]:focus-visible {
  outline: none;
  box-shadow: -16px 0 0 -13px var(--beam);
}
.instrument .pline p[data-placeholder]:empty::before {
  content: attr(data-placeholder);
  color: var(--p-meta);
  pointer-events: none;
}
/* The craft tip from a template slot, beside the words and never in them. It
   is a sentence of advice — "Open on the reader's problem, not the product" —
   so it is sans and sentence case at 11.5. */
.instrument .pline .slot-hint {
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--p-meta);
  margin: 0 0 6px;
}

/* A wording that has just landed. Watched, not discovered later. */
@keyframes instrument-landed {
  0% {
    background: var(--beam-wash);
  }
  100% {
    background: transparent;
  }
}
.instrument .pline.landed {
  animation: instrument-landed 1400ms ease-out;
  border-radius: 6px;
}

/* THE REACH RAIL — how far the rules reach, as a shape in the gutter.
   NO GRADIENT, AND NOT THE SIGNATURE. It was
   `linear-gradient(#0B756F 0%, #E489B6 100%)` on EVERY paragraph, including
   clean ones and the TK note — so `--flag-soft`, the owner-locked "wants a
   look" pink, was being spent as neutral block decoration on content that
   wanted no look, which dilutes the squiggle more effectively than a stray
   pink ever could. Three gradients on a two-paragraph document, against a
   stated maximum of one per view. One hairline in the beam, and it is off
   until somebody asks for it from the rail. */
.instrument .pline[data-reach='on']::before {
  content: '';
  position: absolute;
  right: calc(100% + 8px);
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--beam);
  opacity: 0.4;
}
.instrument .pline.quietnote[data-reach='on']::before {
  background: var(--p-hairline);
  opacity: 1;
}

/* ---------- notices: the frame speaking on the paper --------------------
   Above the words, in the margin note's own material, so a notice reads as
   the instrument talking rather than as a fifth voice. */
.instrument .notice {
  background: var(--note-bg);
  border: 1px solid var(--note-line);
  border-radius: 9px;
  padding: 10px 13px;
  margin: 0 0 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-2);
}
.instrument .notice h5 {
  margin: 0 0 3px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.instrument .notice.stop {
  border-color: var(--flag-soft);
}
.instrument .notice.stop h5 {
  color: var(--flag);
}
.instrument .notice button.inline {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--beam);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.instrument .notice a {
  color: var(--beam);
  text-underline-offset: 3px;
}

/* ---------- bounded ceremonies ------------------------------------------ */
.instrument .scrim {
  position: fixed;
  inset: 0;
  background: rgba(23, 21, 28, 0.44);
  backdrop-filter: blur(2px);
  display: grid;
  place-items: center;
  padding: 28px;
  z-index: 50;
}
.instrument .studio-shell {
  flex: 1;
}
.instrument .copy-toolrail-host,
.instrument .copy-artifact-host,
.instrument .copy-assistant-transcript-host,
.instrument .copy-shared-dock-host {
  width: 100%;
  height: 100%;
  min-height: 0;
}
.instrument .copy-toolrail-host .tools {
  width: 100%;
  height: 100%;
}
.instrument .copy-artifact-host {
  position: relative;
}
.instrument .copy-artifact-host > .paper {
  height: 100%;
}
.instrument .copy-assistant-transcript-host > .agent {
  min-height: 100%;
}
.instrument .copy-studio-dock {
  position: relative;
  width: 100%;
  height: 100%;
}
.instrument .copy-studio-dock .studio-dock__section-body {
  display: block;
  padding: 2px 16px 18px;
}
.instrument .copy-dock-content {
  width: 100%;
  min-width: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-2);
}
.instrument .copy-dock-content [aria-label='Close governed release'] {
  display: none;
}
.instrument .copy-properties {
  display: grid;
  gap: 20px;
}
.instrument .copy-property-choices {
  display: grid;
  gap: 6px;
  margin-top: 10px;
}
.instrument .copy-property-choices button,
.instrument .copy-property-toggle {
  min-height: 44px;
  border: 1px solid var(--note-line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink);
  text-align: left;
  padding: 9px 10px;
}
.instrument .copy-property-choices button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.instrument .copy-property-choices button[aria-pressed='true'],
.instrument .copy-property-toggle[aria-pressed='true'] {
  border-color: var(--beam);
  box-shadow: inset 3px 0 0 var(--beam);
}
.instrument .copy-coverage-rows .figure {
  min-width: 2ch;
  font-size: 24px;
  font-weight: 600;
  line-height: 1;
}
.instrument .review-current {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--note-line);
  border-radius: 9px;
}
.instrument .review-nav { display: flex; gap: 8px; margin-top: 12px }
.instrument .copy-dock-content h4 {
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.instrument .copy-dock-content p {
  margin: 0 0 10px;
}
.instrument .copy-dock-content p:last-child {
  margin-bottom: 0;
}
/* The customer's own words, wherever they are the subject: serif. */
.instrument .copy-dock-content .said,
.instrument .copy-dock-content .rule {
  font-family: var(--serif);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-2);
}
/* THE READOUT IS A SENTENCE, WHICH IS WHY IT IS NO LONGER MONO. What it
   carries, read off the call sites: "Opening the document", "append-only ·
   none editable · nothing is ever rewound", a finding's location, a rule's
   kind and severity. Four sentences and a location; none of them is a thing
   anybody compares character by character. Sans at 11.5, sentence case, and
   the .11em goes with the caps.
   ONE CALL SITE IS LEFT WRONG BY THIS AND IT IS NOT THIS FILE'S TO FIX:
   `CopyStudio.tsx:6898` puts a padded revision number — `04` — in a
   `.readout`. That IS an identifier and wants a class of its own. */
.instrument .readout {
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--ink-3);
}
/* The big number on a coverage row — how many rules are in force, how many
   findings stop a release. A count, in the sans, with tabular figures so a
   column of them still lines up without the face doing it. */
.instrument .figure {
  font-family: var(--sans);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.instrument .figure.stop {
  color: var(--flag);
}
.instrument .rows {
  border: 1px solid var(--note-line);
  border-radius: 9px;
  overflow: hidden;
}
.instrument .rows > li,
.instrument .rows > div {
  display: block;
  padding: 11px 14px;
  border-bottom: 1px solid var(--note-line);
}
.instrument .rows > li:last-child,
.instrument .rows > div:last-child {
  border-bottom: 0;
}
.instrument .rowhead {
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.instrument .rowhead .what {
  flex: 1;
  color: var(--ink);
  font-size: 13.5px;
}
.instrument .why {
  margin: 4px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-3);
}
/* The ceremony's choices — one per row, the chosen one in beam. */
.instrument .choice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 11px 13px;
  border: 1px solid var(--note-line);
  border-radius: 8px;
  cursor: pointer;
  background: var(--surface);
}
.instrument .choice.on {
  border-color: var(--beam);
  background: var(--note-bg);
}
.instrument .choice input {
  margin-top: 3px;
  accent-color: var(--beam);
}
.instrument .choice b {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}
.instrument .choice span {
  display: block;
  font-size: 12.5px;
  color: var(--ink-3);
}
/* Panel buttons: the note's act, at panel scale. */
.instrument .acts-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.instrument .pact {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--note-line);
  border-radius: 7px;
  padding: 8px 14px;
  cursor: pointer;
}
.instrument .pact:hover:not(:disabled):not([aria-disabled='true']) {
  border-color: var(--line-strong);
}
.instrument .pact.primary {
  background: var(--frame);
  border-color: var(--frame);
  color: var(--ink);
}
.instrument .pact.primary:hover:not(:disabled):not([aria-disabled='true']) {
  background: var(--frame-2);
}
/*
 * A REFUSAL HAS TO LOOK LIKE ONE.
 *
 * `:disabled` alone was styled, and the release gate uses `aria-disabled`
 * instead — deliberately, because a `disabled` button leaves the tab order and
 * its `title` is never read out, so the one thing a person needs (what would
 * clear it) is the one thing they cannot reach.
 *
 * MEASURED on the sign-off sheet: the refusing and the open state were
 * pixel-identical, and the only signal was a tooltip on hover. On a governance
 * surface, a control that refuses and looks live is the same failure as a
 * control that looks live and refuses nothing — a person has to press it to
 * find out.
 *
 * RECOLOURED RATHER THAN FADED. This was `opacity: 0.4`. Fading puts the label
 * of a control a person still has to READ — its `title` is where they learn
 * what would clear the refusal — under every contrast floor this product holds
 * itself to. Disabled is a colour, never opacity.
 *
 * AND THE FRAME CARRIES IT, NOT THE LABEL ALONE. Measured next to "Not yet" on
 * the same row, a colour change by itself was one grey against another inside
 * two identical borders on two identical fills — a difference a reader finds by
 * comparing the two, which is not the same as one they see. On the sign-off
 * sheet, where the refusing control sits in a row of three that are not
 * refused, that row read as three live buttons. So the ground and the border
 * step back with the ink.
 *
 * The three are tokens rather than hexes because the refusal has to survive
 * the theme flip — a literal grey is a light-only refusal, drawn in the light
 * palette on a dark screen wherever the sheet inverts around it. And they are
 * `--surface-3`, `--line` and `--ink-3` because that trio is the board's own
 * unavailable ground: `.cta.off` at `pitch.css:741`, `.gh.off` at
 * `pitch.css:724`. A refused control here is the refused control the rest of
 * the product already draws.
 */
.instrument .pact:disabled,
.instrument .pact[aria-disabled='true'] {
  opacity: 1;
  background: var(--surface-3);
  border-color: var(--line);
  color: var(--ink-3);
  cursor: not-allowed;
}
/* The primary's own colours outrank the rule above it, so the refusal is
   restated here rather than lost to specificity — a dark button that refuses
   is the one this sheet opens on, and it lands on the same unavailable ground
   as every other refused control instead of on a second palette of its own. */
.instrument .pact.primary:disabled,
.instrument .pact.primary[aria-disabled='true'] {
  background: var(--surface-3);
  border-color: var(--line);
  color: var(--ink-3);
}
/* "signed off", "unchecked", "a rulebook" — a state word in a small bordered
   tag. State words are English; the border and the colour carry the state,
   the face does not. 11 is the smallest this reads at in the sans. */
.instrument .tagline {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--ink-3);
  border: 1px solid var(--note-line);
  border-radius: 5px;
  padding: 2px 7px;
}
.instrument .tagline.stop {
  color: var(--flag);
  border-color: var(--flag-soft);
}
.instrument .tagline.clear {
  color: var(--beam);
  border-color: var(--beam);
}
.instrument textarea.field,
.instrument input.field {
  width: 100%;
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--note-line);
  border-radius: 8px;
  padding: 9px 11px;
  resize: vertical;
}
.instrument textarea.field:focus,
.instrument input.field:focus {
  outline: none;
  border-color: var(--beam);
}

/* ---------- the left rail: the instruments, as an edge ------------------
   Everything FREQUENT lives here — see the head of `src/copy/Tools.tsx` for
   why, and for what was behind the `···` before it.

   It is the Bench's `DECK` spine's material, deliberately: the same graphite
   gradient off the frame, the same `--frame-line` edge, the same inset
   highlight, the same sans micro-type in its rollovers. Somebody who has used
   one has used this. 44px is what eight glyphs cost the paper; the same eight
   as labelled rows would be a 220px panel arguing with the words. */
.instrument .tools {
  flex: none;
  width: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 0;
  background: linear-gradient(90deg, var(--frame), var(--frame-2) 60%, var(--frame));
  border-right: 1px solid var(--frame-line);
  box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.04);
  z-index: 11;
}
.instrument .tools .tool {
  position: relative;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  border-radius: 6px;
  padding: 0;
  cursor: pointer;
  /* COMPUTED: `#A79FBC` on `#2B2833` is 5.73:1 — the Bench spine's own resting
     colour, and it clears AA for a 1.5px glyph stroke. Hover is `#F4F2F8` on
     `#37333F`, 11.07:1; pressed is `#22E0D5` on `#37333F`, 7.43:1. */
  color: var(--ink-2);
  transition: color 0.12s ease-out;
}
/* The rail's rollovers open to the RIGHT, onto the paper, because the rail is
   against the left edge of the window and the mock's default — centred above —
   was rendering them half off the screen. */
.instrument .tools [data-tip]::after {
  bottom: auto;
  top: 50%;
  left: calc(100% + 9px);
  transform: translateY(-50%);
}
/*
 * NOTHING TO TAKE BACK, AND THE GLYPH SAYS SO.
 *
 * `Undo` and `Redo` are the rail's first controls that can be genuinely
 * inapplicable, and the markup said so — `disabled` was on the button — while
 * the stylesheet did not. Verified in Chromium: at rest and after a delete,
 * both buttons computed `color: rgb(167, 159, 188)`, `opacity: 1`,
 * `cursor: pointer`, and the rail was pixel-identical in the two states. The
 * DOM knew; the screen did not. That is this codebase's most-reported defect
 * wearing the opposite mask — not a dead control that looks live, but a live
 * control that looks the same when it is dead.
 *
 * COMPUTED: `#6B6579` on `#2B2833` is 2.56:1, against the resting glyph's
 * 5.73:1. Deliberately below AA, and allowed to be: WCAG 1.4.3 exempts
 * inactive controls, and a disabled glyph that reads at full strength is a
 * disabled glyph nobody believes. The step from 5.73 to 2.56 is what carries
 * the meaning.
 *
 * IT MUST COME BEFORE `:hover`. `:hover` matches a disabled button in every
 * browser — only the click is suppressed — so with these rules in the other
 * order, pointing at a dead Undo would light it to `--readout-hi` and promise
 * something the press cannot deliver.
 */
.instrument .tools .tool:disabled {
  color: var(--ink-3);
  cursor: default;
}

.instrument .tools .tool:hover:not(:disabled),
.instrument .tools .tool:focus-visible {
  background: var(--frame-2);
  color: var(--readout-hi);
}
.instrument .tools .tool[aria-pressed='true'] {
  background: var(--frame-2);
  color: var(--beam-frame);
}
/* News, as a dot rather than a number: a glyph has no room for a figure, and a
   control carrying a live count is never rare. The count itself is in the
   rollover and in the accessible name. */
.instrument .tools .tool .news {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--flag-soft);
}
.instrument .tools .toolsep {
  width: 18px;
  height: 1px;
  background: var(--frame-line);
  margin: 6px 0;
  flex: none;
}
.instrument .outline {
  background: var(--note-bg);
  border-left: 1px solid var(--note-line);
  overflow-y: auto;
  padding: 14px 0;
  min-height: 0;
}
/* "Blocks" and how many of them. A section's name and a count. */
.instrument .outline .ohead {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 14px 10px;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
}
.instrument .outline .ohead b {
  margin-left: auto;
  color: var(--ink);
  font-weight: 600;
}
.instrument .outline button {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-left: 2px solid transparent;
  padding: 6px 14px;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--ink-2);
}
.instrument .outline button:hover {
  background: var(--surface);
  border-left-color: var(--beam);
}
/* Where the block sits in the document — `01`, `02`. A position, not a name
   for one, so it takes the sans with tabular figures; the 24px column is what
   holds the list straight. */
.instrument .outline button .n {
  font-family: var(--sans);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.instrument .outline button .t {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.instrument .outline button .t.empty {
  color: var(--p-meta);
}
.instrument .outline button .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--flag);
}
.instrument .outline .ofoot {
  margin: 12px 0 0;
  padding: 0 14px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-3);
}

/* The agent pane — the co-reader at length, in the margin's material. */
.instrument .agent {
  background: var(--note-bg);
  border-top: 1px solid var(--note-line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}
.instrument .agent .flow {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
}
.instrument .agent .flow > * + * {
  margin-top: 12px;
}
.instrument .agent .foot {
  flex: none;
  border-top: 1px solid var(--note-line);
  padding: 10px 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

/* ---------- responsive -------------------------------------------------- */
@media (max-width: 900px) {
  .instrument .sheet {
    max-width: none;
    padding: 40px 44px 70px 22px;
  }
  .instrument .sheet::after {
    left: auto;
    right: 22px;
  }
  .instrument .pline.hook p {
    font-size: 20px;
    line-height: 31px;
  }
  .instrument .mmark {
    left: auto;
    right: -44px;
  }
  .instrument .commentmark {
    left: auto;
    right: -24px;
  }
  .instrument .fold .ftag {
    left: auto;
    right: 0;
    top: -40px;
    text-align: right;
    background: var(--paper);
    padding-left: 8px;
  }
  .instrument .note {
    position: fixed;
    left: 12px;
    right: 12px;
    top: auto !important;
    bottom: 118px;
    width: auto;
    z-index: 26;
  }
  .instrument .plate {
    gap: 10px;
    padding: 0 8px 0 12px;
  }
  .instrument .plate .rhs {
    gap: 8px;
  }
  .instrument .plate .rev,
  .instrument .plate .live {
    display: none;
  }
  .instrument .varchip .varlabel {
    display: none;
  }
  .instrument .status {
    gap: 10px;
    padding: 10px 12px;
    font-size: 11px;
  }
  .instrument .status .aux {
    display: none;
  }
  .instrument .capsule .khint {
    display: none;
  }
  .instrument .pline[data-reach='on']::before {
    right: auto;
    left: -12px;
  }
  .instrument .scrim {
    padding: 0;
    place-items: end stretch;
  }
}

@media (max-width: 640px) {
  .instrument .plate {
    grid-template-columns: minmax(0, 1fr) auto;
    display: grid;
    gap: 6px;
    min-height: 56px;
    padding: 4px 6px 4px 10px;
  }
  .instrument .plate .crumb {
    min-width: 0;
  }
  /* The document itself already carries the complete brand context one line
     below. On a phone, repeating that brand inside the narrow identity slot
     makes the document name collapse into a vertical label. Keep the actual
     title here and let the paper retain the full, unabridged heading. */
  .instrument .plate .brandlabel {
    display: none;
  }
  /* `pitch.css` owns the desktop board and has a three-class selector for
     this header. Match the actual composed root here so the phone contract
     wins by scope instead of depending on stylesheet order. */
  .instrument.tPiece.ppboard .pc-hd {
    display: grid;
    gap: 10px;
    margin: 0 14px 22px !important;
    padding: 14px 0 10px !important;
  }
  .instrument.tPiece.ppboard .pc-hd .acts2 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    width: 100%;
    margin-left: 0;
  }
  .instrument.tPiece.ppboard .pc-hd .acts2 button {
    min-width: 0;
    min-height: 44px;
    justify-content: center;
    padding: 7px 5px;
    white-space: normal;
  }
  .instrument .seltool {
    right: 8px !important;
    bottom: calc(var(--copy-console-reserve, 174px) + 12px);
    left: 8px !important;
    top: auto !important;
    width: auto;
    max-width: none;
    max-height: none !important;
    transform: none !important;
    justify-content: center;
    flex-wrap: wrap;
    overflow: visible;
    row-gap: 2px;
    gap: 1px;
  }
}

/* Below 48rem exactly one shared-shell pane is drawn. */
@media (width < 48rem) {
  /* The refusal is a sentence followed by two decisions. At phone width the
     decisions take their own row instead of squeezing the sentence or leaving
     either target outside the answer. */
  .instrument .composer .resp {
    flex-wrap: wrap;
  }
  .instrument .composer .resp > span {
    flex: 1 1 calc(100% - 28px);
    min-width: 0;
  }
  .instrument .composer .resp button {
    flex: 1 1 calc(50% - 4px);
    white-space: normal;
  }
}

@media (prefers-reduced-motion: reduce) {
  .instrument *,
  .instrument *::before,
  .instrument *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- the selection menu flips away from the words -----------------
   Not in the mock, and a defect found while rebuilding from it. `.menu` opens
   downward, which is right under the plate — there is nothing below the plate
   but paper. On the selection surface it is wrong: the surface's preferred
   placement is ABOVE the words, so a downward menu lands on the sentence being
   changed. The carousel's alignment pass found the same thing on a canvas and
   flips there; this is the same fix, and the mock should take it back. */
.instrument .seltool.flip .menu {
  top: auto;
  bottom: calc(100% + 8px);
}

/* The scroller says it is one. A pane that clips a sentence horizontally
   through its middle with no cue reads as a rendering fault. */
.instrument .agent {
  position: relative;
}
.instrument .agent .flow {
  scrollbar-width: thin;
}
.instrument .agent::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 22px;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--note-bg));
}
/* AND IT SAYS IT AT THE SEAM, NOT AT THE FOOT OF THE PANE.
   The fade above is at `.agent`'s own bottom edge, which was the scroller's
   bottom edge until the board's `.pc-foot` arrived and pinned itself there
   with `margin-top: auto` (`pitch.css:548`). Measured on the read-only
   fixture at 1440x900: `.flow` scrolls 882px of cards through 521px and ends
   at y=698; `.pc-foot` runs 698-756; `.agent::after` is at y=756-778, eighty
   pixels below the cut and behind the foot. So a third card below the fold was
   sliced through its verbs by a hard edge with nothing saying it scrolled —
   the exact fault the rule above exists to prevent, moved rather than fixed.

   Drawn on the foot's outside top edge instead: `bottom: 100%` puts it over
   the last 22px of the scroller and above the foot's own hairline, which is
   where the seam actually is. When there is no `.pc-foot` — no record to open
   — the flow reaches `.agent`'s bottom again and the rule above is the cue. */
.instrument .agent .pc-foot {
  position: relative;
}
.instrument .agent .pc-foot::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 22px;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, var(--note-bg));
}

/* ---------- the ways in: a door, opened over the rail -------------------
   Two buttons, a field, four lines of prose and a mono receipt line sat here
   permanently while the finding list scrolled BEHIND them. Reading a file in
   happens once, at the start; it does not earn standing furniture. */
.instrument .agent .waysin {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 8;
  background: var(--surface);
  border-top: 1px solid var(--note-line);
  box-shadow: 0 -8px 30px rgba(23, 21, 28, 0.1);
  padding: 10px 14px 14px;
}
/* The door's own heading — "Read something in". A label on a panel. */
.instrument .agent .waysinhead {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
  margin-bottom: 9px;
}
.instrument .agent .waysinhead .x {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 4px;
}
.instrument .agent .waysinhead .x:hover {
  background: var(--surface-3);
  color: var(--ink);
}
/* SANS. Mono is the exact characters — rule ids, revisions, fingerprints —
   and four lines of explanation in it was the noisiest text on the screen.
   COMPUTED: `#5F5A6E` on `#FFFDF9` is 6.51:1. */
.instrument .agent .waysinsub {
  width: 100%;
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-3);
  margin: 6px 0 0;
}

/* ---------- the margin note has to fit the gutter it actually has --------
   SCREEN-VERIFIED DEFECT, and the root cause under everything the owner called
   noise. The mock sizes the note from the VIEWPORT and centres its sheet,
   because in the mock nothing else is on the screen: half the viewport minus
   half the sheet IS the gutter. In the product an agent pane and an outline
   rail take their own columns, so a CENTRED sheet spends half of what is left
   on an empty LEFT margin the note cannot use.

   Measured at a 1440 window with the pane open: paper 991, sheet centred at
   x=186, gutter 185 for a note needing 272. So the fallback below fired ON A
   DESKTOP and the note rendered `position: fixed`, 1416px wide — 98% of the
   viewport — 301px BELOW its own sentence, over the import block. At 1728 the
   same code was correct, which is how it survived review.

   The gutter is RESERVED now and the words take what is left. `noteGutter.ts`
   holds the reasoning and `noteGutter.test.ts` fails if these numbers and that
   module ever stop agreeing. Below the width where no note fits beside the
   words at all it still falls back to the mock's OWN phone treatment. */
.instrument .paper {
  container-type: inline-size;
}
.instrument .note {
  width: clamp(280px, calc(50cqw - 384px), 300px);

  /* ---------- and it has to say when there is more of it ----------------
     The note is absolutely positioned at its own line's offset inside a paper
     that scrolls, and it had `max-height: none; overflow: visible`. Measured on
     the preview document's first finding at the old 210px measure: 495px tall,
     with nothing anywhere saying whether that was the whole of it. A note that
     is the primary explanation of a release-blocking finding may not run off
     the bottom of the screen silently.

     `62vh` rather than a pixel figure because what it must not exceed is the
     SCREEN, and it is placed by a line offset that CSS cannot see. It is a
     bound, not a placement: the note still opens beside its own sentence, and
     what does not fit is now reachable instead of absent. */
  /* `62vh` is the share of a tall window a note may take. The second term is
     the one that binds on a short one: the paper is not the window — the top
     plate, the console band and the status readout take about 240px between
     them — and a note capped at 62vh of a 520px window is still clipped by the
     paper it lives in. MEASURED at 1512×520: bottom at 499 in a 520 viewport,
     and behind the console. Whichever is smaller. */
  max-height: min(62vh, calc(100vh - 240px));
  overflow-y: auto;
  /* A note is inside a scrolling paper. Without this, reaching the end of the
     note carries on scrolling the document out from under it. */
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;

  /* ---------- and the cue is a shadow, because the bar is not one ---------
     MEASURED, having first written this as a scrollbar: on macOS the bar is an
     overlay. It occupies no layout — `offsetWidth - clientWidth` came back as
     2px, which is the note's own borders — and it is not painted until
     something is already scrolling. A cue that appears once you have found the
     thing it was meant to tell you about is not a cue.
     (`scrollbar-color` does opt an element out of overlay behaviour on Windows
     and Linux, so it stays; it is just not the mechanism this can rely on.)

     So: the shadow trick. Two `local` layers scroll WITH the content and two
     `scroll` layers are pinned to the box, and the local ones sit on top — so
     each shadow is covered exactly while that end of the content is in view,
     and shows exactly when it is not. Nothing measures anything and no state is
     held; being at the top or the bottom of the scroll IS the condition. */
  background:
    linear-gradient(var(--note-bg) 40%, transparent) top / 100% 22px no-repeat local,
    linear-gradient(transparent, var(--note-bg) 60%) bottom / 100% 22px no-repeat local,
    linear-gradient(color-mix(in srgb, var(--ink) 13%, transparent), transparent) top / 100% 9px no-repeat scroll,
    linear-gradient(transparent, color-mix(in srgb, var(--ink) 13%, transparent)) bottom / 100% 9px no-repeat scroll,
    var(--note-bg);
}
/* THE VERBS DO NOT SCROLL AWAY. Capping the height put `Suggest a wording` and
   `Why this is flagged` below the fold of the note's own scroller on anything
   long enough to need capping — trading "the reading runs off the screen" for
   "the two things you can do about it run off the note", which is not a trade.
   Sticky rather than a second element, so the markup is unchanged and the row
   is still in the reading order where it belongs. */
.instrument .note .acts {
  position: sticky;
  bottom: -12px;
  background: var(--note-bg);
  padding-bottom: 12px;
  margin-bottom: -12px;
}
/* The fold's reading has the identical problem and takes the identical answer.
   MEASURED at 1440px with the rules pane docked, when the tag was still
   uppercase mono: `instagram folds here · “…more”`
   rendered as `INSTAGRAM FOLDS HERE · “…MO` — the mock's `white-space: nowrap`
   assumes the mock's gutter, and the product's gutter is the paper's, not the
   window's. So the tag measures the paper too and wraps inside what is actually
   there. `- 336px` is half the 620px measure plus the 26px it sits out at. */
.instrument .fold .ftag {
  white-space: normal;
  /* An explicit WIDTH, not a max-width, and the difference is the whole fix.
     `.ftag` is absolutely positioned at `left: calc(100% + 26px)` inside a
     `.fold` that is only as wide as the sheet, so its containing block offers
     it a negative amount of room. Shrink-to-fit then resolves to the narrowest
     possible box — with `nowrap` it overflowed under the docked pane and was
     clipped mid-word, and with `nowrap` removed it collapsed into a seven-line
     ribbon. Neither is a reading. Told what it has, it uses it. */
  width: clamp(88px, calc(50cqw - 336px), 190px);
}
/* The platform's own control, quoted, and it breaks as one thing. `“…more”`
   split across two lines stops reading as the button somebody taps. */
.instrument .fold .ftag b {
  font-weight: inherit;
  white-space: nowrap;
}
/* 1005, and it moved with the floor rather than on its own. The threshold was
   never the bug — CENTRING was, and `--sheet-left` reserves the gutter instead.
   What WAS still wrong is that the floor the threshold protects was 210px, a
   geometric minimum nobody had set a paragraph in: measured at 1440 and 1512
   with the rules pane open, the rule's own sentence wrapped to nine lines, two
   of them one word. `noteGutter.ts` raises the floor to 280 and this follows
   it, because the two are one number seen from either end — the width at which
   a READABLE note stops fitting beside the words.

   Under it, the mock's own phone treatment, which is the honest trade: a note
   is either readable or it is not, and a column of single words is not a
   degraded note. */
@container (max-width: 1005px) {
  .instrument .note {
    position: fixed;
    left: 12px;
    right: 12px;
    top: auto !important;
    bottom: 118px;
    width: auto;
    z-index: 26;
  }
}

/* The rail's one refusal sentence — same register as the readout it echoes,
   under the list of cards whose verbs point at it. A sentence, so it is set
   in the sans the readout now takes. */
.instrument .agent .rail-refusal {
  margin: 4px 2px 0;
  font-family: var(--sans);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-3);
}
/* Canonical Copy marks: distinguish intent from rule findings without using colour alone. */
.canonical-mark.canonical-bold { font-weight: 700; }
.canonical-mark.canonical-italic { font-style: italic; }
.canonical-mark.canonical-underline { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.12em; }
.canonical-mark.canonical-link { color: inherit; text-decoration: underline; text-decoration-style: solid; }
.canonical-annotation { border-bottom: 2px dotted currentColor; text-decoration: none; }
/* The annotation's kind, printed after the words it marks — "claim",
   "citation". A word for what the mark means, not a code for it. */
.canonical-annotation::after { content: attr(data-annotation); font: 10.5px/1 var(--sans); margin-left: .2em; }

.semantic-mark-menu { position: relative; display: contents; }
.semantic-mark-popover { position: absolute; z-index: 30; top: calc(100% + 8px); left: 0; display: grid; grid-template-columns: repeat(2, minmax(130px, 1fr)); gap: 10px; min-width: 310px; max-width: min(92vw, 480px); padding: 12px; background: var(--paper, #fffdf8); border: 1px solid var(--ink, #25221d); box-shadow: 0 8px 22px rgba(0,0,0,.16); }
.semantic-mark-popover section { display: grid; gap: 4px; }
/* The four group names in "Mark as…" — Structure, Editorial, Projection,
   Intent. Labels over their own buttons. */
.semantic-mark-popover p { margin: 0 0 2px; font: 600 11.5px/1.3 var(--sans); }
.semantic-mark-popover button { min-height: 44px; padding: 8px 10px; text-align: left; background: transparent; border: 1px solid transparent; color: inherit; }
.semantic-mark-popover button:hover:not(:disabled), .semantic-mark-popover button:focus-visible { border-color: currentColor; outline: 2px solid var(--focus, #0b756f); outline-offset: 1px; }
.semantic-mark-popover button:disabled { opacity: .5; cursor: not-allowed; }

/* Structure mode's own chrome, all of it words: the toggle that opens it,
   the section headings ("Installed projections", "Semantic content",
   "Outside normal Copy"), the eyebrow over the title, each node's role and
   state, and the buttons. Labels and sentences — none is an identifier, so
   none is mono. The one thing here that stays a literal is `code`, which has
   no font-family of its own and inherits the page's. */
.structure-toggle { min-height: 44px; padding: 0 10px; border: 1px solid transparent; background: transparent; color: inherit; font: 600 12px/1.3 var(--sans); }
.structure-toggle[aria-pressed="true"] { border-color: currentColor; }
.structure-toggle:focus-visible, .structure-filters button:focus-visible, .structure-mode button:focus-visible { outline: 2px solid var(--focus, #0b756f); outline-offset: 2px; }
.structure-mode { margin: 16px var(--sheet-left, 28px) 28px; padding: 18px; border: 1px solid var(--ink-3, #8c887e); background: var(--paper, #fffdf8); color: var(--ink, #25221d); }
.structure-mode--dock { margin: 0; padding: 0; border: 0; background: transparent; }
.structure-mode header, .structure-node > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.structure-mode h2, .structure-mode h3, .structure-mode p { margin: 0; }
.structure-mode h2 { font: 600 22px/1.1 var(--serif); }
.structure-mode h3 { margin-top: 18px; font: 600 12px/1.3 var(--sans); }
.structure-mode header > div > p, .structure-mode span, .structure-node > p + p { font: 11.5px/1.4 var(--sans); }
.structure-mode button { min-height: 44px; padding: 8px 10px; border: 1px solid var(--ink-3, #8c887e); background: transparent; color: inherit; }
.instrument .outline-list { display: grid; gap: 12px; }
/* The dock's copy of the outline: "Blocks" and a count above it, `01`/`02`
   down the left, and a sentence at the foot saying what the list is for. A
   heading, a position and a paragraph — the same three calls as the rail
   version above, made the same way. */
.instrument .outline-list .ohead { display: flex; align-items: center; justify-content: space-between; font: 600 11.5px/1.3 var(--sans); color: var(--ink-2); }
.instrument .outline-list ul { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.instrument .outline-list button { display: grid; width: 100%; min-height: 44px; grid-template-columns: 28px minmax(0, 1fr) auto; align-items: center; gap: 8px; border: 1px solid var(--line); background: var(--paper); color: var(--ink); padding: 8px; text-align: left; }
.instrument .outline-list .n, .instrument .outline-list .ofoot { font: 11px/1.45 var(--sans); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.instrument .outline-list .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.instrument .outline-list .dot { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--flag); }
.structure-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.structure-filters button[aria-pressed="true"] { background: var(--ink, #25221d); color: var(--paper, #fffdf8); }
.structure-node { display: grid; gap: 6px; padding: 12px 0; border-bottom: 1px solid var(--ink-3, #8c887e); }
.structure-node strong { font: 600 11.5px/1.3 var(--sans); }
.structure-node a { width: max-content; color: inherit; text-underline-offset: .16em; }
/* And the one thing in this block that IS a literal gets the face the rest
   of it gave up: a node id is read character by character or it is not read
   at all. It had no `font-family` and was inheriting the page's sans. */
.structure-node code { overflow-wrap: anywhere; font-family: var(--mono); font-size: 11px; }

.binding-state { display: grid; gap: 6px; min-width: 200px; padding: 8px 10px; border-inline: 1px solid var(--ink-3, #8c887e); }
.binding-state p { margin: 0; }
/* "HEADLINE · Linked" — a role and a state. The caps on the role come from
   `BindingState.tsx:91` and stay its business; the line is a state line, so
   it is sans and the rule adds no caps of its own. Its editor label and its
   two buttons go with it — a label and a verb are words. */
.binding-state__summary { font: 600 11.5px/1.3 var(--sans); }
.binding-state__preview, .binding-state__note { font: 11px/1.35 var(--sans); }
.binding-state button { min-height: 36px; padding: 6px 8px; border: 1px solid var(--ink-3, #8c887e); background: transparent; color: inherit; font: 11.5px/1.3 var(--sans); }
.binding-state__confirm { display: grid; gap: 6px; padding-top: 4px; }
.binding-state__editor { display: grid; gap: 6px; font: 600 11.5px/1.3 var(--sans); }
/* The `letter-spacing: normal; text-transform: none` that used to end this
   rule existed only to undo the label's tracking and caps. The label has
   neither now, so the undoing goes with them. */
.binding-state__editor textarea { width: 100%; min-width: 0; min-height: 72px; resize: vertical; border: 1px solid var(--ink-3, #8c887e); background: transparent; padding: 8px; color: inherit; font: 11px/1.35 var(--sans); }
