/* corporate.css — the Corporate suite layer over suite.css.
   RULED 2026-08-01 (Ritu, at the build's opening): editorial design protocol
   and framework govern; the base colour palette stays; Corporate earns its
   own business-professional feel. This file is that layer's SEED: today it
   carries only the Fact Check register in house grammar (suite tokens,
   hairlines, mono small-caps labels, pills via var(--pill)). The full
   business-feel pass is its own design-plugin slice, not this file's job.
   Loaded AFTER suite.css on corporate pages only. */

/* ── The Fact Check register ─────────────────────────────────────────── */

.fact-bar {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: var(--hairline) solid var(--rule-soft);
}

.fact-bar button {
  font: 600 0.78rem/1 var(--font-mono);
  letter-spacing: normal;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  cursor: pointer;
}

.fact-bar button:hover:not(:disabled),
.fact-bar button:focus-visible:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.fact-bar button:disabled {
  opacity: 0.45;
  cursor: default;
}

.fact-status {
  font: 400 0.8rem/1.5 var(--font-mono);
  color: var(--quiet);
}

.fact-register {
  margin-top: var(--s-3);
  display: grid;
  gap: var(--s-3);
}

.fact-claim {
  border: var(--hairline) solid var(--rule-soft); border-radius: var(--box);
  padding: var(--s-3) var(--s-3);
}

.fact-claim.is-settled { opacity: 0.55; }

.fact-claim-status {
  display: inline-block;
  font: 600 0.68rem/1 var(--font-mono);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--quiet);
  margin-bottom: var(--s-2);
}

.fact-claim-status.is-open { color: var(--warn); }

.fact-claim blockquote {
  margin: 0 0 var(--s-2);
  padding-left: var(--s-2);
  border-left: var(--hairline) solid var(--rule-soft);
  font-family: var(--font-body);
  font-style: italic;
  color: var(--ink-soft);
}

.fact-claim p {
  margin: 0 0 var(--s-2);
  font-size: var(--t-3);
  line-height: calc(var(--s-1) * 6);
  color: var(--ink-soft);
}

.fact-claim-suggestion { color: var(--quiet); }

.fact-claim-action {
  font: 600 0.72rem/1 var(--font-mono);
  letter-spacing: normal;
  color: var(--ink);
  background: transparent;
  border: var(--hairline) solid var(--rule-soft);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  margin-right: var(--s-2);
  min-height: var(--touch-min);
  cursor: pointer;
}

.fact-claim-action:hover,
.fact-claim-action:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

/* ── The two doors ───────────────────────────────────────────────────── */

.door-tabs {
  display: flex;
  gap: var(--s-2);
  margin: var(--s-4) 0 var(--s-1);
}

.door-tab {
  font: 600 0.82rem/1 var(--font-mono);
  letter-spacing: normal;
  color: var(--quiet);
  background: transparent;
  border: 1px solid var(--rule-soft);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  cursor: pointer;
}

.door-tab[aria-pressed="true"] {
  color: var(--accent);
  border-color: var(--accent);
}

.door-tab:hover:not([aria-pressed="true"]),
.door-tab:focus-visible {
  border-color: var(--rule);
  color: var(--ink);
}

/* ── In-copy marks: fact slots and researched additions ──────────────── */

/* The Create door's ask: [completion date]. A quiet mark, not an alarm:
   the slot is an invitation the writer fills, not an error. */
.fact-slot {
  background: transparent;
  color: var(--warn);
  border-bottom: var(--hairline) dashed var(--warn);
  font-style: normal;
}

/* Add Context additions: bold carries the mark in copy/paste; the tint
   makes the researched span visible on the page. */
.added-context {
  font-weight: 600;
  color: var(--accent-deep);
}

/* ── The honesty note (===NOTE=== renders above the letter) ──────────── */

.out-note {
  border: var(--hairline) solid var(--rule-soft); border-radius: var(--box);
  padding: var(--s-3) var(--s-3);
  margin-bottom: var(--s-4);
}

.out-note .out-section-label { color: var(--warn); }

/* ── The polish pass (Ritu's live verdicts, 2026-08-01, parked then built) ── */

/* "Bottom half: CRAMPED." Teach gets its own block, clearly separate from
   the Copy/Export actions; the disclosure summaries take the touch floor. */
.output-actions { margin-top: var(--s-5); }
#teachEditor { margin-top: var(--s-5); }
#teachEditor summary,
#clientEditor summary {
  cursor: pointer;
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
}

/* The letter lands once, whole, and settles — Editorial's reveal
   (editorial-frame.css @keyframes settle), not paragraph-by-paragraph
   streaming. The wait is carried by the status bar AND by the held line. */
@keyframes settle { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.out-section.landed { animation: settle 320ms cubic-bezier(0.22, 0.8, 0.2, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .out-section.landed { animation: none; }
}

/* The held line — the output area says it is working, in the place the letter
   will appear. Ritu's ruling 2026-08-02: a measured 5.7s call showed three
   status-bar steps at 0.25s / 2.2s / 4.8s in a 51px strip at the foot of the
   window, and he read the page as doing nothing. Same dot and same mono
   register as the status bar, so the two read as one voice rather than two
   indicators competing. It is a placeholder and never the letter in pieces. */
.working-line {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-display); font-size-adjust: var(--x-adjust);
  font-size: var(--t-2);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--quiet);
  padding: var(--s-4) 0;
  margin: 0;
}
.working-dot {
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--mark);
  animation: pulse 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .working-dot { animation: none; }
}

/* Press feedback (emil law: a button must respond to the press). Feedback
   on the press only, never on the disabled state.

   Compose is a main action and takes the deep press; the door tabs and the
   fact bar are secondary and keep the depth they had. Both depths and the one
   curve are declared in icons.css, which is the only sheet these pages and the
   Editorial tools both load. Read the reasoning there. */
.compose:active:not(:disabled) { transform: scale(var(--press-deep)); }
.door-tab:active,
.fact-bar button:active:not(:disabled) { transform: scale(var(--press-light)); }
.compose:active:not(:disabled),
.door-tab:active,
.fact-bar button:active:not(:disabled) {
  transition: transform var(--press-in) var(--press-ease), border-color 0.15s ease, color 0.15s ease;
}
.compose, .door-tab, .fact-bar button { transition: transform var(--press-out) var(--press-ease), border-color 0.15s ease, color 0.15s ease; }

/* Clear — Editorial's appears-only-with-text pattern, now in the house pill.
   It kept its 44px height but sat in --quiet at the far right of a ~1300px
   row, which is how Ritu missed it on his own tool. Warn colour is held for
   hover: an eraser should announce itself when reached for, not before. */
.quiet-clear {
  appearance: none;
  background: transparent;
  border: var(--hairline) solid var(--rule-soft);
  border-radius: var(--pill);
  font-family: var(--font-display); font-size-adjust: var(--x-adjust);
  font-size: var(--t-2);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.quiet-clear:hover,
.quiet-clear:focus-visible { color: var(--warn); border-color: var(--warn); }

/* The label row holds the mono label and whatever control follows it on one
   line. */
/* Ritu's catch, 2026-08-02: "SPEAK touching the box." The row was
   align-items:baseline with the bottom margin living on the LABEL only. That
   worked while Speak was a 21px underlined word; once it became a 44px pill its
   box hung below the label's baseline, ate the 0.6rem and sat on the textarea.
   Same failure as the IntroDoctor alt-card header: a control with a real box
   has no useful text baseline. Centre the row and move the clearance onto the
   ROW, so whichever child is tallest keeps the gap. */
.label-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
}
.label-row .mono-label { margin-bottom: 0; }
/* THE MARK SITS ON THE BOX, NOT IN THE MIDDLE OF A ROW THAT GREW.
   The row is centred, and that is Ritu's own call from 2026-08-18: topping it
   left "Your draft" and "Lane" at different heights, and he named it. Centring
   is right while the row is one line tall, which it is at every width this
   page was ever measured at.

   It stops being right the moment the label wraps. MEASURED at 320, where "A
   real moment, only if you want one told" takes two lines: the row grows from
   44px to 59.4px, the 44px mark stays centred in it, and the gap between the
   mark and the box it belongs to goes from 8px to 15.7px. The mark is placed
   against the box, so it is the mark that must hold the row's bottom edge.

   align-self on the marks alone, not align-items on the row: the label keeps
   the centring he ruled for, and on a one-line row the marks ARE the tallest
   child, so this changes nothing at any width where nothing wraps. */
.label-row .box-tools { align-self: flex-end; }

/* ── The clip and the mic, on every box (2026-09-08) ───────────────────────
   This page carried seven bespoke Speak buttons and two Import buttons,
   wired by hand to the browser's own speech engine and a plain-text file
   reader. Ritu, 2026-09-08: "Convert client-letters to the shared mic too",
   then: "Yes, replace the controls... I want this functionality where every
   box will accept a word, PDF, and audio." Every textarea on this page now
   carries the suite's own pair instead, wired by assets/js/box-tools.js: the
   clip reads text, markdown, Word, PDF and dictates audio; the mic dictates
   directly through assets/js/dictate.js. Both hear all 23 languages and hand
   back English.

   .box-tools / .box-tool / .box-tools-msg are editorial-frame.css's classes,
   and that sheet is not loaded here: corporate.css is its own layer over
   suite.css (see the file header) and stays separate from the newsroom
   frame on purpose. So the rules the pair needs are restated below in
   corporate's own tokens, sized to sit on a .label-row exactly where Speak
   and Import sat, rather than pulling in editorial's sheet (and its
   wc-display/harvest-hint furniture, which this page has none of) whole.

   THREE CORRECTIONS, measured on the render with
   scripts/box_tools_align_check.mjs (extended 2026-09-08 to reach corporate
   pages by scanning for this same marker, not only shell/tools.json's
   editorial list). The first two are PORTED FROM editorial-frame.css, not
   reinvented, because they are general and not editorial-specific. Ritu,
   2026-08-20: "the alignments are awry."

   (1) THE RIGHT EDGE: a 16px glyph centred in a 44px tap target leaves 14px
   of empty target outside it, so aligning the BUTTON to the row's edge
   leaves the mark sitting 14px short of it. margin-right pulls the row back
   by exactly that difference, which puts the glyph flush with the content
   edge and leaves the tap target where it was.

   (2) THE POSITION: with the words Speak and Import gone, position is most
   of what makes an unlabelled mark findable, and the house rule is that a
   shared affordance looks identical everywhere. margin-left:auto puts the
   pair on its box's right edge on every row, so it sits at the same x
   whether the label beside it is "Material" or "A real moment, only if you
   want one told".

   (3) THE GAP ABOVE THE BOX, NOT PORTED, MEASURED FRESH. Editorial holds
   this at 8px by making its .box-tools take NO height on a label row
   (height: 0, a negative margin on .box-tool) so the row's own height comes
   from the label alone, typically 16 to 20px there, and a small top nudge
   (2 to 4px) closes what is left. Corporate's .label-row is not that row:
   Ritu's ruling of 2026-08-02, above, fixed align-items:center and put the
   clearance ON THE ROW specifically because the control was already a 44px
   pill and the row was built to hold it at full height, not to shrink
   around it. So the row here measures 44px before and after this change,
   by design, and the same height-collapse trick would shrink it, moving
   the label and breaking that ruling. The gap instead measured 22px (14px
   of empty button below the 16px glyph, the same 14px as correction 1,
   plus the row's own 8px margin-bottom) at every one of the nine boxes and
   every width once corrections 1 and 2 above were in place and a stray
   #lexImport button rule (below) stopped leaking onto lexPasteBox's pair.
   top: 14px moves the mark down by exactly that surplus, which is a
   position:relative offset: it repaints the mark 14px lower without
   changing the row's box model, so the row's height and the label's
   position are exactly what they were. Confirmed after: 8.0px at every
   box, every width; see the fix report for the full table.

   (4) THE BUTTON FOOTPRINT, FIXED 2026-09-08 FOR THE WHOLE SUITE. Moving the
   MARK to 8px above the box with top: 14px also moves the 44px BUTTON around
   it, whose bottom edge then sits 6px past the box's top edge, and because
   .box-tools is position:relative it paints over the textarea in that strip
   regardless of DOM order. On this page the ROW's own box overhangs by the
   same 6px, so it took clicks there too. It read as a corporate-only defect
   until editorial was measured: DeskCopy_V3_0.html #inputCopy,
   FieldReportage's six section boxes, ReporterAlly's two, IntroDoctor's one,
   on both an .input-label row and a standalone one, all measured the same 6.0
   to 6.4px, at 1440 and at 390. It was never a corporate regression; it was a
   suite-wide condition the align gate could not see, because the gate measures
   the mark, which is exactly 8px, and not the button, which is not. It is now
   fixed in both sheets the same way, and no mark moved: see the matching block
   at the end of editorial-frame.css's alignment section for the reasoning. */
.box-tools {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: none;
  margin-left: auto;
  margin-right: calc((var(--touch-min) - var(--t-3)) / -2);
  position: relative;
  top: 14px;
  /* Correction 4 above. The row and the buttons keep the boxes they are
     drawn in; the pointer stops at the textarea's top edge. */
  pointer-events: none;
}
.box-tool {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  width: var(--touch-min);
  height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--pill);
  cursor: pointer;
  font-size: var(--t-3);
  line-height: 0;
  flex: none;
  position: relative;
  pointer-events: none;
  transition: color 160ms ease, background-color 160ms ease;
}
.box-tool::after {
  content: '';
  position: absolute;
  inset: 0 0 calc((var(--touch-min) - var(--t-3)) / 2 - var(--s-2) + 1px) 0;
  pointer-events: auto;
}
.box-tool:hover { --ico-color: var(--ink); }
.box-tool:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Listening, filled rather than dimmed: an accent disc with the mark cut out
   in paper says ON without spending a colour this page has not already
   spent on the door tabs and the theme toggle. Ported from
   editorial-frame.css's identical rule (box-tool-breath), not reinvented. */
.box-tool[aria-pressed="true"] {
  background: var(--accent);
  --ico-color: var(--paper);
  animation: box-tool-breath 1.6s cubic-bezier(0.37, 0, 0.63, 1) infinite;
}
@keyframes box-tool-breath {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.09); }
}
@media (prefers-reduced-motion: reduce) {
  .box-tool[aria-pressed="true"] { animation: none; }
}

/* What prints here: a file that would not read, a recording that failed, or
   a moment of progress worth naming (reading a file, transcribing a
   recording, takes a beat). Failure takes --warn, the same voice this page's
   own .error-msg already reserves for the house error grammar, below.
   Progress is not a failure and does not wear one's colour: --quiet is the
   tone .fact-status already carries for a notice that asks nothing of the
   reader, so a beat of "reading this file" does not read as bad news.

   ONE AFFORDANCE, ONE VOICE. This line is the same line as editorial's: same
   class, same script writing into it, the same two things ever printed there.
   It wore a different face, 0.8rem roman mono against editorial's italic body
   type, so the one message a reporter meets on both halves of the suite read
   as two different notices. Editorial's treatment is the one that stands, in
   corporate's own tokens: body face, --t-2, italic, no tracking and no case
   change, and the leading inherited rather than pinned, exactly as
   editorial-frame.css leaves it. */
.box-tools-msg {
  display: none;
  font-family: var(--font-body);
  font-size: var(--t-2);
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  color: var(--warn);
  margin: 0 0 var(--s-2);
}
.box-tools-msg.is-shown { display: block; }
.box-tools-msg.is-progress { color: var(--quiet); }

/* The offer to send a held recording again: a word inside the line, not a
   third mark on the label row. It takes the line's own type and colour, in
   Corporate's tokens, and underlines itself to say it is a control. */
.box-tools-again {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin-left: var(--s-2);
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.box-tools-again:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.box-tools-again:disabled { cursor: default; opacity: 0.5; }

/* Failures wear the house error grammar (warn hairline), never the
   letter's own clothes. */
.error-msg {
  border: var(--hairline) solid var(--warn);
  padding: var(--s-3) var(--s-3);
  margin-top: var(--s-4);
  font-size: var(--t-3);
  line-height: calc(var(--s-1) * 6);
  color: var(--ink-soft);
}

/* ============================================================
   NIGHT — Ritu's ruling 2026-08-01: Corporate offers two options,
   day and night. suite.css is deliberately day-only (the known
   divergence on record at DESIGN-SYSTEM.md); Corporate themes at
   its own layer instead of touching the shared sheet, so the front
   door and editorial.html stay exactly as they are.

   The palette is the editorial night vocabulary (editorial-frame.css
   [data-theme="night"]) re-declared over the suite tokens — one house
   night, not a second one. Two deliberate departures:

   · --rule / --rule-soft are lifted, not copied. suite.css lifted its
     day hairlines because this sheet's thesis is that rule lines do
     the structural work (finding 25: --rule 2.96:1, --rule-soft
     1.52:1). The editorial night values (#34353A / #2A2B2F) measure
     1.5:1 / 1.3:1 on this dark paper — the soft tier, twice. The same
     two floors re-derived on #16171A: --rule #63666D 2.9:1,
     --rule-soft #34353A 1.5:1.
   · No --cta-ink token exists in suite.css; the pressed toggle
     segment uses var(--paper) (#16171A on teal #56B6BF, 6.9:1).
   ============================================================ */

[data-theme="night"] {
  --paper:       #16171A;
  --paper-deep:  #1F2024;
  --paper-warm:  #1F2024;
  --ink:         #ECE7DC;
  --ink-soft:    #C3BDB0;
  --quiet:       #989185;
  --rule:        #63666D;
  --rule-soft:   #34353A;
  --accent:      #56B6BF;
  --accent-deep: #1E4F80;
  --mark:        #CBA15A;
  --good:        #86A86E;
  --warn:        #D98C53;
}

/* Paper texture reads as noise on a dark ground — same suppression as
   editorial-frame.css's night. */
[data-theme="night"] body::before { display: none; }

/* The masthead is brand chrome and does not theme (Ritu's ruling
   2026-08-02, the editorial tool law applied here: "the banner must retain
   its colour so that the word mark doesn't change"). The banner keeps its
   day colours in night, deliberately hardcoded, and the wordmark renders
   in its own ink untouched. The footer mark sits on the themed page, so
   it takes the editorial night footer's quiet invert instead. */
[data-theme="night"] .masthead {
  background: #E9EDED;
  border-bottom-color: #868A8A;
}
[data-theme="night"] .masthead .suite-mark { color: #6B6259; }
[data-theme="night"] .masthead .theme-toggle,
[data-theme="night"] .masthead .theme-toggle button { border-color: #868A8A; }
[data-theme="night"] .masthead .theme-toggle button { color: #6B6259; }
[data-theme="night"] .masthead .theme-toggle button:hover { color: #1A1717; }
[data-theme="night"] .masthead .theme-toggle button[aria-pressed="true"] { background: #187079; color: #E9EDED; }
[data-theme="night"] .foot .copy img { filter: brightness(0) invert(1); opacity: 0.55; }

/* ── Masthead utility cluster + the Day/Night control ─────────────────
   The toggle component is the editorial masthead capsule (editorial-frame.css
   .theme-toggle) ported onto suite tokens: corporate pages do not load that
   sheet. Same geometry laws — the 44px floor lives on the capsule, buttons
   stretch into it; pill the group, clip the segments. */

.masthead-utility {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}

.theme-toggle {
  display: inline-flex;
  align-items: stretch;
  min-height: var(--touch-min);
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  overflow: hidden;
}
.theme-toggle button {
  font-family: var(--font-display); font-size-adjust: var(--x-adjust);
  font-size: var(--t-1);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  background: transparent;
  color: var(--quiet);
  border: 0;
  border-left: 1px solid var(--rule);
  padding: 0 var(--s-2);
  min-height: 0;
  min-width: var(--touch-min);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease;
}
.theme-toggle button:first-child { border-left: 0; }
.theme-toggle button:hover { color: var(--ink); }
.theme-toggle button[aria-pressed="true"] { background: var(--accent); color: var(--paper); }
.theme-toggle button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }


/* Per-band text sizes, appended by preview/build-precision.mjs
   --apply-type. The product's root font is a clamp, so one rem is a
   different number of pixels at each width and a single mapped value
   would be wrong everywhere except the width it was mapped at. These
   carry identical specificity to the rule above and come later, which is
   how the narrower band wins. */
@media (max-width: 620px) {
.quiet-clear {
  font-size: var(--t-1);
}
}
@media (max-width: 430px) {
.working-line {
  font-size: var(--t-1);
}
}

/* ── The configuration rail ───────────────────────────────────────────────
   Ritu, 2026-08-18: "all the selection panels should be on the left-hand
   side, just like in editorial and social", and then: "I want it to be
   thinner."

   Editorial's rail is --rail: 18rem, declared in editorial-frame.css and used
   by the five desks and Scroll Desk. Corporate does NOT load that sheet: it is
   the newsroom frame, and Corporate is not editorial. So the width is declared
   here, at 15rem, and the two suites differ by intent rather than by accident.

   What is in the rail is configuration: the lane, whether the web is
   consulted, and whose voice the letter carries. What is NOT in it is the
   door, because choosing a door replaces the whole input form and that is not
   a setting. ------------------------------------------------------------- */

:root {
  /* SEVEN SPACING STEPS for the whole product, replacing thirteen. Applied
     2026-08-10 from the styling preview.

     Values under 4px are left alone: below the base step there is no step to
     round to, and a 1px nudge is usually doing optical work a scale should not
     overrule.

     INLINE padding and margin are only ever REDUCED, never raised. Raising them
     narrows the column the text is set in, and a narrower column is how a
     paragraph gains a line. Measured: rounding to nearest added a line to five
     paragraphs on corporate and social at 390. See inlineAt() in
     preview/build-precision.mjs for which positions of a shorthand count as
     inline. */
  --s-1:         4px;
  --s-2:         8px;
  --s-3:         16px;
  --s-4:         24px;
  --s-5:         40px;
  --s-6:         64px;
  --s-7:         104px;
  /* The Corporate rail. Editorial declares --rail: 18rem in
     editorial-frame.css; Corporate is thinner and owns its own token, so the
     two suites differ by intent and Corporate never loads the newsroom frame. */
  --cl-rail: 16.5rem;
  /* EIGHT TEXT SIZES for the whole product, replacing fifteen. Applied
     2026-08-10 from the styling preview, and the LAST of the five steps because
     it is the only one that can change where a word breaks.

     The fifteen fractional sizes had one cause and it was not a second scale:
     the root font is 18px and sizes were written in rem, so 0.7rem is 12.6px.

     h1 IS EXCLUDED. Bringing headlines onto this scale turns eight of them from
     one line into two across five tools, because the scale jumps 40px straight
     to 68px and today's tool headlines sit at 55.66 and 62.7. Measured
     2026-08-10; the gap in the scale is the real defect and is its own job. */
  --t-1:         12px;
  --t-2:         14px;
  --t-3:         16px;
  --t-4:         19px;
  --t-5:         23px;
  --t-6:         28px;
  --t-7:         40px;
  --t-8:         68px;
  /* TWO TRACKING VALUES for the whole product, replacing ten. Applied
     2026-08-10 from the styling preview.

     --track-caps is for text the sheet also sets in uppercase. Capitals need
     the air; a sentence does not, which is why positive tracking on mixed-case
     text goes to plain normal here rather than to 0.16em. That would be grotesque
     on a sentence, and 26 selectors were carrying it.

     --track-tight is the only negative value. h1 keeps its own: loosening
     DeskTriage's and FieldReportage's headline from -0.03em to -0.01em wrapped
     both onto two lines, and the line count wins.

     NOT DONE HERE: the trailing letter-space. CSS puts the tracking after the
     LAST character too, so a centred or right-aligned capped label sits half a
     tracking left of where it should. Cancelling it means adding a negative
     margin to 160 rules, which is a second decision and gets measured on its
     own. */
  --track-tight: -0.01em;
  --track-caps:  0.16em;
  /* One rule weight for the whole product. 0.5px, not 1px: at 1px a divider
     between two panel rows carries the same weight as the edge of a control,
     and the page reads as a grid of boxes rather than as a page with rules in
     it. Applied 2026-08-10 from the styling preview, where it measured 0 FAIL
     and 0 rewraps across 2,226 elements at three widths.
     A control's border is NOT neutralised with it: see the note in
     hairlineMap(). --edge, the 3:1 control boundary, is a separate step. */
  --hairline:    0.5px;
}

.cl-config {
  display: grid;
  grid-template-columns: var(--cl-rail) minmax(0, 1fr);
  align-items: stretch;
  border-top: var(--hairline) solid var(--rule-soft);
  border-bottom: var(--hairline) solid var(--rule-soft);
  margin: var(--s-5) 0;
}

/* No fill. Editorial's panel is tinted because it carries eight or nine cells
   and needs to read as a body; this rail carries four, and a tinted column
   running the full height of a tall output area is a slab of dead paper rather
   than a panel. The right-hand rule does the structural work on its own. */
.cl-rail {
  border-right: var(--hairline) solid var(--rule-soft);
  min-width: 0;
}

/* One cell per decision, divided by the same hairline that divides the rail
   from the work. The last cell carries no rule, so the rail ends on the
   container's own border rather than on a doubled line. */
.cl-cell {
  padding: var(--s-3);
  border-bottom: var(--hairline) solid var(--rule-soft);
  min-width: 0;
}
.cl-rail > .cl-cell:last-child { border-bottom: 0; }

.cl-cell > label {
  display: block;
  font: 600 0.68rem/1.2 var(--font-mono);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-2);
}

/* A select in the rail takes the full width and the touch floor. The suite
   sheet leaves .selector select without a min-height, which measured 39px at
   620px and below; nothing that ships from here inherits that. */
.cl-cell select {
  width: 100%;
  min-height: var(--touch-min);
  font: 500 0.85rem/1.3 var(--font-sans);
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
}
.cl-cell select:hover { border-color: var(--ink-soft); }
.cl-cell select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The work column. Its own left padding rather than a margin on the first
   child, so the input, the letter and the register all start on one line. */
.cl-work {
  min-width: 0;
  padding: var(--s-1) 0 var(--s-4) var(--s-5);
}
.cl-work > *:first-child { margin-top: 0; }



/* Below the suite's own two-column threshold the rail stops being a rail: it
   becomes a band above the work, with the cells sharing the row until they
   cannot. The border moves from the right edge to the bottom so the band
   still reads as one group. */
@media (max-width: 867px) {
  .cl-config { grid-template-columns: minmax(0, 1fr); }
  .cl-rail {
    border-right: 0;
    border-bottom: var(--hairline) solid var(--rule-soft);
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  }
  .cl-rail > .cl-cell { border-bottom: 0; border-right: var(--hairline) solid var(--rule-soft); }
  .cl-rail > .cl-cell:last-child { border-right: 0; }
  /* The editor spans the band: its three fields never belong in a column. */
  #clientEditor.cl-cell {
    grid-column: 1 / -1;
    border-top: var(--hairline) solid var(--rule-soft);
    border-right: 0;
  }
  .cl-work { padding: var(--s-4) 0 0; }
}

/* ── The voice editor, out of the rail ────────────────────────────────────
   Ritu, 2026-08-18: "aren't the panels on the left-hand side too small for
   input?" They were. Measured in the rail: the voice-notes box held about 120
   characters, and its own placeholder is 95. A 15rem column is right for
   choosing and wrong for authoring, so the three fields moved to the working
   width and the trigger stayed behind. ---------------------------------- */

/* The trigger wears the door tabs' type exactly, because it is the same kind
   of control and it read as a caption before. */
/* SYMMETRY INSIDE THE RAIL (Ritu, 2026-08-18: "everything inside that rail,
   there should be symmetry"). Every control in the rail is one shape: full
   width, the touch height, the same border, radius, padding and type. The
   trigger therefore takes the SELECT's type rather than the door tab's, which
   reverses his earlier note that it should read like "Start from an idea".
   That note was about it looking inert; matching its neighbours answers the
   same complaint and keeps the cell it lives in coherent. */
button.cl-trigger {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-2);
  width: 100%;
  margin-top: var(--s-2);
  font: 500 0.85rem/1.3 var(--font-sans);
  letter-spacing: normal;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  cursor: pointer;
  text-align: left;
}
button.cl-trigger:hover { color: var(--ink); border-color: var(--ink-soft); }
.cl-trigger[aria-expanded="true"] { color: var(--accent); border-color: var(--accent); }
button.cl-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.cl-editor { padding-top: var(--s-3); }
.cl-editor-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
  padding-bottom: var(--s-3);
  border-bottom: var(--hairline) solid var(--rule-soft);
}
.cl-editor-title { font: 600 1.05rem/1.2 var(--font-sans); color: var(--ink); margin: 0; }
button.cl-back {
  font: 600 0.78rem/1 var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
}
button.cl-back:hover { border-color: var(--ink-soft); }

/* Name and notes share a row while there is room. The name is a single line
   and was a textarea pretending to be one. */
.cl-editor-grid {
  display: grid;
  grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
  gap: var(--s-4);
  margin-top: var(--s-4);
}
.cl-editor-grid input[type="text"] {
  width: 100%;
  min-height: var(--touch-min);
  font: 400 0.95rem/1.4 var(--font-sans);
  color: var(--ink);
  background: var(--paper-deep);
  border: 1px solid var(--rule-soft);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
}
.cl-editor-grid textarea { min-height: 7rem; }
@media (max-width: 720px) { .cl-editor-grid { grid-template-columns: minmax(0, 1fr); } }

/* The lexicon is a table, not a syntax. The pipe in "avoid | use" existed only
   because the box was narrow; with columns there is nothing to explain, and
   the third column carries the evidence behind each supplied row. */
.cl-lex { margin-top: var(--s-5); }
.cl-lex-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.cl-lex-head h3 { margin: 0; }
.cl-lex-head button {
  font: 600 0.72rem/1 var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
}
.cl-lex-table { margin-top: var(--s-3); }
.cl-lex-row {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 15rem) minmax(0, 1fr) auto;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-2) 0;
  border-bottom: var(--hairline) solid var(--rule-soft);
}
.cl-lex-header {
  font: 600 0.68rem/1.2 var(--font-mono);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-bottom: var(--s-2);
}
.cl-lex-row input[type="text"] {
  width: 100%;
  min-height: var(--touch-min);
  font: 400 0.88rem/1.3 var(--font-sans);
  color: var(--ink);
  background: var(--paper-deep);
  border: 1px solid var(--rule-soft);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
}
.lex-why { font: 400 0.78rem/1.45 var(--font-sans); color: var(--ink-soft); }
button.lex-drop {
  font: 600 0.68rem/1 var(--font-mono);
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--pill);
  padding: var(--s-2);
  min-height: var(--touch-min);
  cursor: pointer;
}
button.lex-drop:hover { color: var(--ink); border-color: var(--rule); }
@media (max-width: 720px) {
  .cl-lex-row { grid-template-columns: minmax(0, 1fr); }
  .cl-lex-header { display: none; }
}
#lexImport { margin-top: var(--s-4); }
#lexImport summary { cursor: pointer; min-height: var(--touch-min); display: flex; align-items: center; }
/* > not a descendant selector: #lexPasteBtn ("Add these") is the only
   button this rule is for, and it is a direct child of the <details>. A
   plain `#lexImport button` also caught the box-tools pair once box-tools.js
   started nesting a marker inside this same <details> for #lexPasteBox
   (2026-09-08): its 1px border and margin-top landed on a .box-tool that
   declares neither, and the alignment gate measured the result as a ~1.5 to
   2px residual on both axes for that one box alone. Found by measuring, not
   by reading either rule in isolation. */
#lexImport > button {
  font: 600 0.72rem/1 var(--font-mono);
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--pill);
  padding: var(--s-2) var(--s-3);
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
  margin-top: var(--s-2);
}

/* ── Three faults the audit measured, fixed inside Corporate ──────────────
   The suite sheet owns all three and is shared with Editorial, so the fix is
   scoped here rather than changing six other pages. ---------------------- */

/* 1. The label and its Speak button sat centred in their row, which pushed
      "Your draft" 52px below "Lane" beside it. Ritu saw it as a gap between
      the rule and the controls. The two now open on the same line. */
/* The label and its Speak button stay on ONE line, centred against each
   other. Ritu, 2026-08-18: "look at how your draft stacks behind Speak" was
   the cost of my first attempt, which topped the row to close the gap and left
   the two texts at different heights. The row keeps its own alignment; the
   whole row moves up instead, so "Your draft" and "Lane" open together. */
.cl-work .label-row { align-items: center; }
#letterWork > div > .source-block:first-child { margin-top: 0; }

/* 2. Copy and Export ship disabled and measured 1.75:1 in day, which is close
      to invisible, against a comment on this page arguing they must be seen
      from load. Legible, still plainly inert. */
.cl-work .output-actions button:disabled { opacity: 0.68; color: var(--ink-soft); }

/* 3. The primary action measured 33px tall at every width, under the 44px
      floor Ritu set on 2026-07-28. */
.cl-work .compose { min-height: var(--touch-min); }

/* ── Teach in the masthead, and the footer in editorial's shape ───────────
   Ritu, 2026-08-18: "Teach can go to the masthead. Why I have something
   hanging right there at the bottom." And: "the footer is downright ugly. Why
   not follow the aesthetic that we used for editorial and social."
   ---------------------------------------------------------------------- */

/* Teach wears editorial's masthead treatment exactly, not an invention of
   mine. Ritu, 2026-08-18: "Teach looks like somebody has sucked the life out
   of the button. Is it the same as teach in editorial? No, it isn't." It was
   an outlined ghost; editorial's is a filled navy capsule. The literal values
   are copied from .mast-nav-link in editorial-frame.css, including its note
   that neither colour themes, because Corporate must not load that sheet. */
button.mast-action {
  font-family: var(--font-display);
  font-size-adjust: var(--x-adjust);
  font-size: var(--t-1);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: #FBFAF6;
  background: #082A4C;
  --ico-color: currentColor;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--touch-min);
  padding: var(--s-2) var(--s-3);
  border: 0;
  border-radius: var(--pill);
  cursor: pointer;
}
button.mast-action:hover { background: #156169; color: #FBFAF6; }
button.mast-action[aria-expanded="true"] { background: #156169; }
button.mast-action:focus-visible { outline: 2px solid #082A4C; outline-offset: 2px; }

/* The suite link stays left, the colophon groups right and reads as one
   block, which is what editorial-frame.css does for the desks. Corporate does
   not load that sheet, so the shape is restated rather than imported. */
.foot { align-items: flex-end; gap: var(--s-3); flex-wrap: nowrap; }
.foot .back { margin-top: 0; }
.foot .colophon {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  align-items: flex-end;
  text-align: right;
  margin-left: auto;
}
.foot .colophon .copy { display: inline-flex; align-items: center; gap: var(--s-1); flex-wrap: wrap; }

/* ON A PHONE THE FOOTER STACKS, BECAUSE THE ROW CANNOT HOLD IT.
   `nowrap` above is right on a desk and wrong below it: forbidding the ROW to
   break does not make the content fit, it makes the suite link break inside
   itself, CORPORATE over SUITE with one underline running under both lines,
   while the colophon sits beside it on a different baseline. suite.css's base
   .foot wraps; only the corporate pages carry the override, which is why only
   they showed it.
   MEASURED at 1440, with every item at its own max-content width and nothing
   squeezed, item widths plus gaps plus the page's 144px of side padding:
     client-letters  161 + 234 + 16  + 144 = 555px of viewport
     the-brief       234 + 148 + 161 + 32 + 144 = 719px
     the-record      the same three items, the same 719px
   corporate/index.html loads suite.css alone, never took the override, and is
   not in this. 719 is the first width at which a corporate footer stops
   fitting, so it is where all three stack: the suite link on its own line, the
   colophon under it, both flush left, nothing breaking mid phrase. Above it
   nothing changes at all. */
@media (max-width: 719px) {
  .foot { flex-wrap: wrap; align-items: flex-start; }
  .foot > * { width: 100%; }
  .foot .colophon { margin-left: 0; align-items: flex-start; text-align: left; }
  /* suite.css pushes the powered-by line right with margin-left:auto,
     "regardless of siblings". Stacked, there is no right to push to: it is
     the last line of a left-aligned block. */
  .foot .powered { margin-left: 0; }
}

/* The draft box's own row: two actions, no label. The label is present for
   screen readers and hidden from sight, because "Your draft" over "Paste your
   draft." says one thing twice. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.label-row.is-actions { gap: var(--s-2); }

/* The hero, matching the editorial desks (Ritu, 2026-08-18: "I want the hero
   to look like this, for the sake of uniformity"). Headline, then the
   description directly under it: no eyebrow, no rule between them, and the
   headline in the page ink rather than the accent. editorial-frame.css caps
   the description at 50em; Corporate does not load that sheet, so the cap is
   restated here. */
.lede.tool-desc { max-width: 50em; }

/* A marked field in the rail. A native <select> cannot render an icon inside
   an option, so the mark sits on the control itself and the select is padded
   to clear it. The mark is inert to the pointer, so the whole pill still opens
   the menu. */
.cl-field { position: relative; }
.cl-field > .ico {
  position: absolute;
  left: var(--s-3);
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  color: var(--ink-soft);
  display: inline-flex;
}
.cl-field select { padding-left: calc(var(--s-3) + 1.4rem); }

/* The hero opens at the same distance from the masthead rule as the editorial
   desks. Ritu asked whether the gap matched; measured at 1440 it did not,
   72px here against 63px on DeskCopy, because .page carries a fluid top
   padding this hero does not need. --s-6 is the scale value nearest their
   figure, so the two open together without a magic number. */
main.page { padding-top: var(--s-6); }

/* The doors are a switch, not two buttons. Ritu, 2026-08-18, having pressed
   "Start from an idea" and found four boxes: "tell me how to close." The way
   back was the other tab, marked only by a slightly different border, which is
   too quiet for a control that swaps the whole form. This is the same
   segmented shape as the DAY/NIGHT toggle already in his masthead: joined,
   with the live one filled, so "you are here, press the other" needs no
   explaining. */
.door-tabs { gap: 0; display: inline-flex; border: var(--hairline) solid var(--rule-soft); border-radius: var(--pill); overflow: hidden; }
.door-tab { border: 0; border-radius: 0; border-left: 1px solid var(--rule); }
.door-tab:first-child { border-left: 0; }
.door-tab[aria-pressed="true"] { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.door-tab[aria-pressed="true"] .ico { color: var(--paper); }
.door-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A dropdown must look like a dropdown. Ritu, 2026-08-18: "what does your
   input do? If I click that button, what happens?" He read a select as a
   button, and he was right to: giving it a pill and a left-hand mark, with no
   arrow on the right, left nothing to say it opens a list. Every select in the
   rail now carries the arrow, which also separates it from the trigger
   beneath it, which IS a button. */
.cl-cell select {
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 1rem) calc(50% + 2px),
    calc(100% - 0.7rem) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: calc(var(--s-3) + 1rem);
}

/* ---- One pointer target per gated button (2026-08-20) ----
   The copy handler and the fact-check resist gate judge ev.target by exact
   id. A click landing on the icon or label span would slip both while the
   auto-teach listener still fired. The inner marks go inert so every
   listener sees the same target: the button. */
#copyBtn > span, #exportBtn > span { pointer-events: none; }
