/* tw-metro-kit.css - the Studio's shared components.
 *
 * Built ONCE so eleven surfaces share a foundation instead of inventing it
 * eleven times. That is the thing that makes a single autonomous pass safe: the
 * risk in one go is not volume, it is a wrong assumption applied consistently
 * everywhere. A shared kit means one correction fixes every surface.
 *
 * Requires tw-metro-tokens.css. Every value here comes from a token; there are
 * no literals, so both themes resolve without this file knowing about themes.
 *
 * ── THE RULES THIS KIT ENFORCES ─────────────────────────────────────────────
 *  1. NO rounded corners, NO shadows, NO gradients on chrome.
 *  2. FAMILY COLOUR FILLS TILES. STATE IS ONLY EVER A CHIP, DOT OR STRIPE.
 *     A filled block is identity; a small mark is state. This is what keeps
 *     sound-gold and warning-amber from being confused.
 *  3. Tight gutters. The grid separates; borders mostly do not exist.
 *  4. Type carries hierarchy - Gotham's light weights at size, never a second
 *     family. The serif was dropped 2026-08-20.
 *  5. A click changes what you look at, never where you are. Only labelled
 *     doors navigate (design book, binding).
 */

.m-app { background: var(--m-ground); color: var(--m-ink); font: var(--m-body); }

/* Raw <b>/<strong> default to the browser's UA bold (700) unless told
   otherwise, and this system does not use weight as its emphasis channel at
   all - see the file banner, "Type carries hierarchy... never a second
   family", and tw-metro-tokens.css's "a heading is a LIGHTER body, not a
   bigger one". A blanket reset for the register modal's own root class,
   landing on --m-micro's weight (500), the ladder's ceiling. */
.m-app b, .m-app strong { font-weight: 500; }
/* tw-register-modal.css set .twrm-term-v/.twrm-line strong/.twrm-slidecap b
   off-ladder (700/600/700). Corrected AT SOURCE in that file on 2026-08-23
   rather than out-specified from here - one source of truth per rule. */

/* ── TYPE ─────────────────────────────────────────────────────────────────── */
.m-display { font: var(--m-display); letter-spacing: -.035em; }
.m-title   { font: var(--m-title);   letter-spacing: -.025em; }
.m-heading { font: var(--m-heading); letter-spacing: -.015em; }
.m-subhead { font: var(--m-subhead); letter-spacing: -.012em; }
.m-lede    { font: var(--m-body-lite); color: var(--m-ink-2); max-width: 64ch; }
.m-quiet   { color: var(--m-ink-3); }
.m-data    { font: var(--m-data); font-variant-numeric: tabular-nums;
             letter-spacing: -.02em; }
/* ALL CAPS micro-label. Metro's workhorse; always tracked, never bold. */
.m-micro   { font: var(--m-micro); letter-spacing: var(--m-track);
             text-transform: uppercase; color: var(--m-ink-3); }
.m-micro--accent { color: var(--m-accent-text); }

/* ── GRID ─────────────────────────────────────────────────────────────────── */
.m-grid   { display: grid; gap: var(--m-gap); }
.m-grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.m-grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.m-grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.m-span   { grid-column: 1 / -1; }
/* One language, mobile and desktop: the same grid at a different column count.
   Ruled 2026-08-20 - mobile is not a separate treatment. */
@media (max-width: 1000px) { .m-grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 640px)  { .m-grid-2, .m-grid-3, .m-grid-4 { grid-template-columns: 1fr; } }

/* ── TILE - the unit ──────────────────────────────────────────────────────── */
/* ★ `color: inherit` IS LOAD-BEARING, and it was missing until 2026-08-22.
   A <button class="m-tile"> does NOT inherit colour - buttons take the UA's
   `buttontext`, which is BLACK. The Capture tool renders all 79 show cards as
   buttons, so every title and episode count on that grid was black text on a
   dark ground: present in the DOM, sized correctly, and unreadable.
   Found by LOOKING at the surface. The contrast gate had passed, because it
   sampled body-text pairs and never a button descendant - a measurement can
   only clear what it thought to measure. Same reason `font: inherit` is here:
   a button does not take the page's face either. */
.m-tile { background: var(--m-tile); padding: var(--m-pad); border-radius: 0;
          display: flex; flex-direction: column; position: relative;
          color: inherit; font: inherit; text-align: inherit;
          transition: background var(--m-dur-state) var(--m-ease-state); }
.m-tile:hover { background: var(--m-tile-2); }
/* ★ A ROW TILE. Added 2026-08-23 from the Capture tool, where THREE surfaces
   wanted one - a resume banner, an episode row and a capture row - and each
   had silently restated `flex-direction: row` to undo the default above.
   Three workarounds for one missing modifier is the kit failing to express
   something real, not three careless authors. The column default is still
   right for a tile of stacked facts; this names the other case. */
.m-tile--row  { flex-direction: row; align-items: center; }
.m-tile--lg   { padding: var(--m-pad-lg); }
.m-tile--sunk { background: var(--m-tile-2); }
.m-tile--quiet{ background: transparent; border: 1px solid var(--m-edge); }
/* A FILLED tile is identity - the bank's family, or a call to act. */
.m-tile--fill { background: var(--m-accent); color: var(--m-accent-ink); }
.m-tile--fill .m-micro,
.m-tile--fill .m-quiet,
.m-tile--fill .m-data { color: rgba(0,0,0,.62); }

/* ── STATE - chips, dots, stripes. NEVER a tile fill. ─────────────────────── */
.m-chip { display: inline-flex; align-items: center; gap: 6px;
          font: var(--m-micro); letter-spacing: .1em; text-transform: uppercase;
          padding: 6px 9px; border-radius: 0; }
.m-chip--ok   { background: var(--m-ok-bg);   color: var(--m-ok); }
.m-chip--warn { background: var(--m-warn-bg); color: var(--m-warn); }
.m-chip--err  { background: var(--m-err-bg);  color: var(--m-err); }
.m-chip--rest { background: var(--m-rest-bg); color: var(--m-rest); }
/* ★★ THE STATE THAT IS NOT A PROBLEM (D6, 2026-09-07). "2 to check" is a
   count of things nobody has looked at yet - not a fault, not a warning, and
   it was drawn in amber next to error red as though it were both. Amber is a
   third hue the language does not have (C5), and it made the quietest state
   on the panel the loudest mark on it.
   Same chip, same geometry - the FORM is what carries "this is a state", per
   the rule that identity fills tiles and state is only ever a chip, dot or
   stripe. Only the ink is quiet. Tokens on both sides, so it follows the
   theme like every other chip. */
.m-chip--quiet { background: var(--m-tile); color: var(--m-ink-2); }
.m-dot { width: 8px; height: 8px; display: inline-block; }
.m-dot--ok { background: var(--m-ok); } .m-dot--warn { background: var(--m-warn); }
.m-dot--err{ background: var(--m-err); } .m-dot--rest{ background: var(--m-rest); }
/* A stripe states severity on a row without colouring the row. */
.m-stripe { border-left: 3px solid var(--m-edge); padding-left: 13px; }
.m-stripe--ok  { border-left-color: var(--m-ok); }
.m-stripe--warn{ border-left-color: var(--m-warn); }
.m-stripe--err { border-left-color: var(--m-err); }

/* ── CONTROLS ─────────────────────────────────────────────────────────────── */
/* ⚠ THE TRACK IS THE TOKEN, not a number typed here (2026-09-07). This read
   .13em while every other all-caps label in the language reads --m-track's
   .18em - so a button and the label above it were set differently on the same
   panel, which is the drift Andrew named looking at the Bank and the Inspector
   together: "the labels are different fonts". One number, one token. The
   Components artboard states the button as `--m-micro · .18em · 44px · square`. */
.m-btn { font: var(--m-micro); letter-spacing: var(--m-track); text-transform: uppercase;
         padding: 13px 18px; border-radius: 0; cursor: pointer;
         background: transparent; border: 1px solid var(--m-edge-strong);
         color: var(--m-ink-2); transition: border-color var(--m-dur-state) var(--m-ease-state); 
  /* 44px floor for a thumb - the assembled-page gate measured these at
     39px, which is a control designed for a mouse. */
  min-height: 44px; display: inline-flex; align-items: center; justify-content: center;}
.m-btn:hover { border-color: var(--m-ink-3); color: var(--m-ink); }
.m-btn:focus-visible { outline: 2px solid var(--m-focus); outline-offset: 2px; }
/* IDENTITY is the fill (accent background); the label does not also need
   to be bold on top of it - that was a second, off-ladder emphasis channel
   stacked on the first. Weight stays at --m-micro's 500, the ladder's ceiling.

   ★★ THE PRIMARY ACTION IS INK (Andrew, ruling 1 of 2026-09-08, on the visual
   study's A11). This fill was --m-act blue on every surface while every
   artboard drew it as --m-ink: `Components.dc.html:39`,
   `.btn--key{ background:var(--m-ink); border-color:var(--m-ink);
   color:var(--m-ground); }`. The artboards are the spec, and the reason is
   the language's own first rule - identity and state separate by FORM, not by
   hue. Danger red is the ONE meaningful hue; blue carried no meaning, which
   is exactly why nobody noticed it disagreeing with every drawing for weeks.

   ⚠ --m-act IS NO LONGER A BUTTON COLOUR. It stays in the token file because
   --m-focus resolves to the same value and a focus RING is not a fill: a ring
   is a state drawn outside the control, which is the form/hue split working
   as intended. If a new control reaches for --m-act as a background, that is
   this repaint growing back. Gate: check F in
   _test-ux-components-speak-one-language.js. */
.m-btn--key { background: var(--m-key); border-color: var(--m-key);
              color: var(--m-key-ink); }
/* ★ A FILLED BUTTON KEEPS ITS ON-FILL INK ON HOVER.
   `.m-btn:hover` above sets `color: var(--m-ink)`, which is right for the
   OUTLINE buttons - their grey label darkens to ink. Both selectors are
   (0,2,0), so source order decides and this rule wins only where the two
   overlap; it declared background and border and never restated colour, so
   the outline rule's ink applied to a FILLED control. In light that is
   #0A0A0A text on a #3B3B3B fill - black on black.
   Andrew, 2026-09-11, on the Slides Editor NEXT button: "it appears black
   on black when in a touch interface ... a side effect of being touched and
   therefore highlighted". On a pointer it flashes only while hovering, which
   is how it survived; on touch :hover STICKS after the tap, so the control
   the person just pressed is the one they cannot read. */
.m-btn--key:hover { background: var(--m-ink-2); border-color: var(--m-ink-2);
                    color: var(--m-key-ink); }

/* ── THE IRREVERSIBLE ONE ────────────────────────────────────────────────
   Delete, remove, reject, end game. It is filled, not merely red text: a
   destructive control should be as loud as its consequence. It is the ONLY
   other coloured button, and the pair is chosen so that a person with any
   dichromacy can still tell them apart - dE >= 91 under all three. */
.m-btn--danger { background: var(--m-act-danger); border-color: var(--m-act-danger);
                 color: var(--m-act-danger-ink); }
/* Same fault, same fix: the danger fill is the other filled control. */
.m-btn--danger:hover { background: var(--m-act-danger-2); border-color: var(--m-act-danger-2);
                       color: var(--m-act-danger-ink); }

/* ── THE FOURTH KIND: UNAVAILABLE ────────────────────────────────────────
   Components artboard, 2026-09-07: "Four kinds, no more: primary, quiet,
   commit, unavailable." The kit had three, so a control at its bound had
   nowhere to go but a sentence explaining the bound - which is the shape
   this project rules out. Unavailable is STILL THERE and still says what it
   would do; it simply will not do it. Quieter than the edge, never removed:
   a control that vanishes at its limit teaches nothing about the limit. */
.m-btn--off, .m-btn[disabled], .m-btn[aria-disabled="true"] {
  /* ★ QUIET IS NOT INVISIBLE, AND THE BOUNDARY IS NOT THE DIVIDER. This drew
     its edge with --m-edge, the DIVIDER colour at about 1.45:1 - a rule the
     estate already has a gate for, because a control boundary at divider
     contrast reads as an absence rather than as a limit. The comment above is
     right and the colour contradicted it. --m-edge-strong keeps the control's
     shape at a boundary contrast; the ink carries the unavailability, which is
     what "quieter" was always supposed to mean. The raw #B4B4B4 went with it:
     an off-ladder hex in the kit is how a second palette starts. */
  color: var(--m-ink-3); border-color: var(--m-edge-strong); cursor: default;
  background: transparent;
}
.m-btn--off:hover, .m-btn[disabled]:hover, .m-btn[aria-disabled="true"]:hover {
  border-color: var(--m-edge-strong); color: var(--m-ink-3);
}

.m-field { display: block; }
.m-field > .m-micro { display: block; margin-bottom: 7px; }
/* ★★ 44px IS THE FLOOR FOR A THUMB (2026-08-23), on the CONTROL and not
   behind a media query: a target too small at 375px is also too small on a
   touchscreen laptop. Measured in the live modal before this: five inputs at
   20px. `font` must be set explicitly too - a bare control inherits Arial from
   the UA sheet, not the page. */
.m-input, .m-textarea, .m-select {
  width: 100%; box-sizing: border-box; border-radius: 0;
  background: var(--m-ground); color: var(--m-ink);
  border: 1px solid var(--m-edge-strong); padding: 11px 12px; font: var(--m-body);
  min-height: 44px;
}
.m-textarea { min-height: 88px; }
.m-input:focus-visible, .m-textarea:focus-visible, .m-select:focus-visible {
  outline: 2px solid var(--m-focus); outline-offset: 1px; border-color: transparent;
}
/* An unwritten field is an INVITATION, not an error. 135 unwritten working
   lines in red would make the bank look broken when it is merely unfinished - 
   and would train the author to ignore red. */
.m-empty { border-style: dashed; }
.m-empty-note { font: var(--m-body-lite); color: var(--m-ink-3); margin-top: 8px; }

/* ── AUDIO - its own world, in both themes ────────────────────────────────── */
.m-audio { background: var(--m-audio); color: var(--m-audio-ink); padding: var(--m-pad-lg); }
.m-audio .m-micro { color: var(--m-audio-ink); opacity: .75; }
.m-wave { position: relative; height: 82px; margin-top: 16px;
          background: var(--m-audio-2); overflow: hidden; }
.m-wave canvas { display: block; width: 100%; height: 100%; }
/* The chosen window: lit against the dimmed whole. */
.m-window { position: absolute; top: 0; bottom: 0;
            background: color-mix(in srgb, var(--m-accent) 18%, transparent);
            border-left: 3px solid var(--m-accent-2);
            border-right: 3px solid var(--m-accent-2); }

/* ── MOTION - fast and directional. Never decorative. ─────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .m-enter { animation: m-slide var(--m-dur-enter) var(--m-ease-enter) both; }
  .m-enter:nth-child(2) { animation-delay: var(--m-stagger); }
  .m-enter:nth-child(3) { animation-delay: calc(var(--m-stagger) * 2); }
  .m-enter:nth-child(4) { animation-delay: calc(var(--m-stagger) * 3); }
  .m-enter:nth-child(5) { animation-delay: calc(var(--m-stagger) * 4); }
  @keyframes m-slide { from { opacity: 0; transform: translateX(26px); }
                       to   { opacity: 1; transform: none; } }
}
@media (prefers-reduced-motion: reduce) { .m-enter { animation: none; } }


/* ⚠ `display: inline-flex` on .m-btn OVERRODE the UA's [hidden] rule, so a
   button hidden in JS stayed on screen - the decision rail showed "Save to the
   bank" when there was nothing to save. Setting `display` on a component
   silently breaks `hidden` unless you say this. */
[hidden] { display: none !important; }


/* ═══════════════════════════════════════════════════════════════════════
   FIELD CONTROLS FOR THE DECLARED KINDS (2026-08-22)
   Eight kinds were declared across the registers and none was rendered -
   they all fell through to a plain text box. These are the controls the
   register modal now builds for colour, scrim and zone. A declaration that
   names a kind nobody renders is a promise the surface silently breaks.
   ═══════════════════════════════════════════════════════════════════════ */
.m-swatches { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.m-swatch {
  flex: 0 0 44px; width: 44px; height: 44px; min-width: 44px; min-height: 44px;
  padding: 0; cursor: pointer;
  border: 1px solid var(--m-edge-strong); border-radius: 0;
  /* It carries no text, and it was still Arial: a bare <button> takes the UA
     sheet's face, not the page's (C2), and a typeface counts whether or not a
     glyph lands on it - the swatch was one of the entry modal's seven. */
  font: var(--m-micro); font-family: var(--m-sans); letter-spacing: var(--m-track);
  text-transform: uppercase;
}
.m-swatch[aria-pressed="true"] { outline: 2px solid var(--m-focus); outline-offset: 1px; }

/* The colour a mechanic DERIVED, offered as the leading swatch: pressing it
   clears the author's override and returns the slide to its pictures' own
   colour. Dashed, so a derived value never looks like an authored one. */
.m-swatch--derived { border-style: dashed; border-width: 2px; }

/* The well. A declared palette is a shortcut, not the limit - a ground
   sampled from a photograph is any of 16 million values. Sized to the swatch
   row so the two read as one control, not a control and an afterthought. */
.m-colourwell {
  flex: 0 0 44px; width: 44px; height: 44px; min-width: 44px; min-height: 44px;
  padding: 0; cursor: pointer;
  border: 1px solid var(--m-edge-strong); border-radius: 0; background: none;
}
.m-colourwell::-webkit-color-swatch-wrapper { padding: 2px; }
.m-colourwell::-webkit-color-swatch { border: none; }
.m-colourwell::-moz-color-swatch { border: none; }

.m-scrim { display: grid; grid-template-columns: 1fr auto; gap: 6px; align-items: center; margin-top: 6px; }
.m-scrim input[type="range"] { width: 130px; accent-color: var(--m-accent); }

/* Four numbers on one line: x, y, w, h on the 1920x1080 canvas. */
.m-zone { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin-top: 6px; }
.m-zone .m-input { text-align: center; }

/* A list of authored lines (kind:'answer_list'). Held as lines, never as one
   string with separators - a haiku with a comma mid-line would be mangled by
   anything that split it back apart. */
.m-answer-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.m-answer-row  { display: grid; grid-template-columns: 1fr auto; gap: 4px; }
.m-btn--quiet  { background: transparent; border: 1px solid var(--m-edge-strong); color: var(--m-ink-3); }
.m-btn--quiet:hover { color: var(--m-ink); border-color: var(--m-ink-3); }
.m-field--media .m-btn { margin-top: 6px; }

/* ── THE OPTION VOCABULARY - one set of parts, two surfaces ────────────────
   Ruled 2026-09-07 from the Components artboard, after Andrew put the Bank
   and the Inspector side by side: "the labels are different fonts", the tick
   boxes have no specified size, the A-H option weights are inconsistent.

   The two surfaces have different ROLES - the Bank keeps the record, the
   Inspector edits the slide in front of you - and that is the whole of the
   permitted divergence. The PARTS are one set. A different height, ramp,
   radius, tick or label for a shared control is drift, and goes.

   ⚠ EVERY RULE HERE RESTATES font-family AFTER the `font` shorthand. `font:
     var(--m-micro)` resets font-family to the UA default, because the
     shorthand sets every font property and --m-micro's own trailing
     var(--m-sans) does not survive a nested substitution in every engine.
     Six mono fields died silently to exactly this on 2026-09-06, with every
     gate green. */

/* The target: what a thumb hits. Never given a border - the box inside it is
   the thing you see. */
.m-tgt { width: var(--m-target); height: var(--m-target); flex: 0 0 auto;
         display: inline-flex; align-items: center; justify-content: center;
         cursor: pointer; background: none; border: 0; padding: 0; }
.m-tgt:focus-visible { outline: 2px solid var(--m-focus); outline-offset: -4px; }

/* The mark: what the eye reads. --m-edge-strong because this hairline IS the
   control, not a divider between two areas - WCAG 1.4.11 asks 3:1 of it, and
   --m-edge is 1.45:1 here. */
.m-tick { width: var(--m-target-box); height: var(--m-target-box);
          box-sizing: border-box; border: 1px solid var(--m-edge-strong);
          background: var(--m-ground); border-radius: 0;
          display: inline-flex; align-items: center; justify-content: center;
          color: var(--m-ground); }
/* TWO MARKS, NOT ONE MARK IN TWO COLOURS. A tick in a second colour reads as
   a second kind of right answer; correct is the ok green, and the one that
   can never be the answer is a CROSS in ink. */
.m-tick--on { border-color: var(--m-ok); background: var(--m-ok); }
.m-tick--no { border-color: var(--m-ink); background: var(--m-ink); }

/* ★★ THE NATIVE FORM OF THE SAME MARK (bible C1, 2026-09-08).
   Not every tick in the estate is a span the builder paints. Where a register
   marks MANY correct answers - Identify ticks four of eight - the control is a
   real `<input type="checkbox">`, because the row means "one of several" and
   a checkbox is what that is. Left to the user agent it drew two different
   things on the two surfaces, measured on 2026-09-07 with one question open
   in each:

       Slides Inspector, .v7i .m-radio       37 x 44   (a 44px rule squeezed
                                                        to 37 by its flex row)
       Bank entry modal, .m-radio            13 x 13   (the UA default)

   One class, one meaning, two products - the exact drift the component
   chapter was written to end. Andrew, on the Inspector: "I thought the UX
   specifications created a more subtle tick element." A 44px native checkbox
   is not a big target, it is a big GLYPH.

   So the native input is given the SAME box the span form has: 20px
   (--m-target-box), square, hairline in --m-edge-strong, filled --m-ok when
   checked, with the tick drawn from the same 11x11 path _paintTick uses in
   tw-register-modal.js. THE 44px IS NOT ON THE INPUT - C1 puts it on the
   wrapping label or grid cell, which is where a click on the label already
   lands. A rule that gives the input itself 44px has to choose between the
   box and the target, and it always chooses wrong.

   ⚠ THE MARK IS DRAWN, NOT SHRUNK. `appearance: none` is what makes the box
     ours; without it the UA keeps its own control and every property below is
     advisory. */
/* ⚠ `.m-radio` IS THE NAME ALREADY IN THE MARKUP, and it is an m- class, so
   the kit is where it belongs - it had never been declared here, only in
   tw-metro-fields.css under `.v7i`, which is why the Bank got the UA default.
   Both names are listed on every rule so a later markup pass can move to
   `.m-tick-native` without a second drawing appearing in between. */
.m-tick-native, .m-radio {
  appearance: none; -webkit-appearance: none;
  width: var(--m-target-box); height: var(--m-target-box);
  min-width: var(--m-target-box); min-height: var(--m-target-box);
  flex: 0 0 auto; margin: 0; padding: 0;
  box-sizing: border-box; border: 1px solid var(--m-edge-strong);
  background: var(--m-ground); border-radius: 0; cursor: pointer;
  background-repeat: no-repeat; background-position: center;
  background-size: 11px 11px;
}
.m-tick-native:checked, .m-radio:checked {
  border-color: var(--m-ok); background-color: var(--m-ok);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M2.2 5.6 L4.4 7.9 L8.8 3.2' stroke='%23FFFFFF' stroke-width='1.8'/%3E%3C/svg%3E");
}
.m-tick-native:focus-visible, .m-radio:focus-visible { outline: 2px solid var(--m-focus); outline-offset: 2px; }
/* The hit area is the LABEL's, and it is the same 44px the span form's target
   is. Clicking a label toggles the input it wraps, so this is a real target
   and not a decorative box around a small one. */
.m-tgt-label { display: inline-flex; align-items: center; justify-content: center;
               width: var(--m-target); height: var(--m-target); flex: 0 0 auto;
               cursor: pointer; }

/* ★★ THE TICK AS A WHOLE FIELD (bible C1, Andrew 2026-09-08).
   "For picture GK and MC questions, it should be a simple tick box somewhere
   in the inspector and bank." A tick that answers a QUESTION ABOUT THE ROW -
   rather than marking one option among several - is a row of its own: the
   kit's 20px box in its 44px target, then the writer's sentence, and the row
   tints when it is on. Same tint token as `.m-opt--on`, because it is the
   same fact said the same way.

   ⚠ THE TICK IS THE ONLY MARKER (C1). No badge, no second word, no "(set)".
     Three markers for one fact is what the components chapter was written to
     end.

   ⚠ THE TYPE SELECTOR IS LOAD-BEARING, NOT DECORATION. `.v7i .m-field` in
     tw-metro-fields.css is (0,2,0) and loads AFTER this file on the Slides
     Editor, so a bare `.m-field--tick` would lose `display` on one of the two
     surfaces and win it on the other - one control drawn two ways, which is
     the drift this whole chapter exists to end. `label.m-field.m-field--tick`
     is (0,2,1) and therefore wins on BOTH regardless of order. One drawing.

   ⚠ AND THE WORDS ARE NOT `.m-micro`. That class is uppercased by the
     Inspector's field rule and left sentence-case by the Bank's; a shared
     control cannot borrow a class that means two things. */
/* The metrics are `.m-opt`'s, to the pixel: same 44px floor, same 12px gap
   between the target and the words, same side padding. A tick row and an
   option row are the same shape doing the same job, and two spacings for one
   shape is how a surface stops reading as one product. */
label.m-field.m-field--tick {
  display: flex; align-items: center; gap: var(--m-s-3);
  min-height: var(--m-target); box-sizing: border-box; cursor: pointer;
  padding: 0 var(--m-s-3); margin: 0 0 var(--m-s-3);
}
label.m-field.m-field--ticked { background: var(--m-ok-bg); }
.m-field--tick > .m-tick-words {
  font: var(--m-body); font-family: var(--m-sans);
  color: var(--m-ink); text-transform: none; letter-spacing: normal;
  margin: 0; display: inline;
}

/* The option row. State is a block of colour, not furniture: a correct answer
   is a tinted row and needs no stripe and no badge. */
.m-opt { display: flex; align-items: center; gap: var(--m-s-3);
         min-height: var(--m-target); padding: 0 var(--m-s-3); box-sizing: border-box; }
.m-opt--on { background: var(--m-ok-bg); }

/* ★ THE LETTER IS 500 AND UNTRACKED. It was set at .1em in one surface and
   .18em in another - tracking on a SINGLE character is spacing applied to
   nothing, and it moved the letter off the column the ticks line up against.
   ★★ THE COLUMN IS 24px, AND IT IS THE ONLY WIDTH (2026-09-08, C-7).
   This read 13px; .twrm-term-v read min-width 1.2em; the option grid read
   44px whether the row could be reordered or not; Music Themed measured 13x11
   and Multiple Point 44x11. Four numbers for one glyph. bible-components C4
   names two and only two - 24px (--m-s-6) on a row you cannot reorder, 44px
   (--m-target) on one you can, because there the letter IS the drag handle -
   and the Components artboard draws the read-only column at 24. 13px is under
   the width of a capital H at 11px with any breathing room at all, which is
   why the option texts were still not landing on one edge. */
.m-ltr { width: var(--m-s-6, 24px); flex: 0 0 auto; font: var(--m-micro);
         font-family: var(--m-sans); letter-spacing: 0; color: var(--m-ink-3); }
.m-otx { flex: 1 1 auto; min-width: 0; font: var(--m-body);
         font-family: var(--m-sans); color: var(--m-ink); }

/* The Studio wordmark follows Andrew's instruction: Works is bold.
   Preserve its size and spacing while sharing the same light/bold order
   across both Bank and Slides markup shapes. */
.m-wordmark {
  font: 500 13px/1 var(--m-sans); letter-spacing: var(--m-track-mark); text-transform: uppercase;
  color: var(--m-ink); text-decoration: none; white-space: nowrap;
  display: inline-flex; align-items: baseline;
}
.m-wordmark:hover { text-decoration: none; }
.m-wordmark .tw-brand-mark { font: inherit; letter-spacing: inherit; color: inherit; }
/* TWO SHAPES, one rule. The Slides bar puts .m-wordmark on the <a> and lets
   TW_BRAND.mount() write .tw-brand-mark INSIDE it; the Bank's nav puts both
   classes on ONE span. A descendant selector alone silently misses the second
   shape - and a wordmark that is right on one surface and wrong on the next is
   the exact fault this rule exists to close. (0,3,1), above the module's own
   (0,2,0), its .tw-brand--sm (0,2,0) and its dark-theme rule (0,3,1).) */
.m-wordmark .tw-brand-mark > span.tw-brand-thin,
.m-wordmark.tw-brand-mark  > span.tw-brand-thin { font-weight: var(--m-mark-w1); color: inherit; }
.m-wordmark .tw-brand-mark > span.tw-brand-bold,
.m-wordmark.tw-brand-mark  > span.tw-brand-bold { font-weight: var(--m-mark-w2); color: inherit; }
html[data-theme="dark"] .m-wordmark .tw-brand-mark > span.tw-brand-bold,
html[data-theme="dark"] .m-wordmark.tw-brand-mark  > span.tw-brand-bold { color: inherit; }

/* ── THE SURFACE PAIR ─────────────────────────────────────────────────────
   Slides | Book. ONE control with two states, joined with no gap between
   them, because the Book is a first-class editing surface and a lone outlined
   link beside Save did not say that.

   ★★ IT LIVES IN THE KIT BECAUSE IT IS WORN BY TWO SURFACES (2026-09-09).
   It was written privately on the Slides bar, and the Book - the other half
   of the same pair - had no way back at all (visual study D-1). A control
   that names BOTH surfaces cannot be owned by one of them. _shared/
   tw-v7-surface-pair.js builds the markup; this is its only styling, and it
   keeps ONLY what the kit has no opinion about: where the two cells sit
   against each other. Colour, type, tracking and the 44px thumb floor all
   come from .m-btn / .m-btn--key above, one home.

   The cells overlap by a pixel so the pair draws ONE shared edge down the
   middle rather than two edges with a hairline of ground between them. */
.m-surface-pair { display: flex; align-items: stretch; flex: 0 0 auto; }
/* No `white-space: nowrap` here, deliberately: both labels are single words,
   so it could only ever be defensive - and a nowrap row in a shared sheet is
   a real finding on the 390 census, paid by every surface that loads the kit
   for a wrap that cannot happen. */
.m-surface-pair > * { padding: 0 var(--m-s-4); display: inline-flex;
  align-items: center; text-decoration: none; }
.m-surface-pair > * + * { margin-left: -1px; }
/* ★ AND THE PHONE RULE IS NOT HERE, ON PURPOSE (D3, 2026-09-07: a COMPONENT
   asks its CONTAINER; only a SHELL asks the WINDOW). Hiding the half that
   names the surface you are already on is not a fact about the pair - it is a
   fact about a bar that has run out of room. The Slides bar is one row that
   does not wrap and measured 506px of want against 390px of screen, so it
   drops that half; the Book's bar wraps and was measured at 390x844 with both
   halves and zero overflow, so it keeps it - and on the Book that half is the
   only place the surface is named at all. Each bar states its own, in its own
   sheet, where asking the window is what a shell is for. */
