/* The button marks, styled once for every suite.

   Ritu, 2026-08-05: "I hope you have maintained symmetry in icons (across the
   project)" and "Should not be limited to Editorial".

   This lives in its own sheet because the pages that carry marks load
   different stylesheets: the Editorial tools load editorial-frame.css, the
   front door and Corporate load suite.css, Social loads social-dark.css. The
   rules were in editorial-frame.css alone, so every mark outside Editorial
   rendered unstyled. One sheet, linked from all of them, rather than the same
   block copied into three.

   THE PRESS TOKENS DO NOT LIVE HERE, and the attempt to put them here on
   2026-08-17 is worth recording. This is the only sheet every surface loads,
   so it looked like the one place a product-wide control law could live. It is
   not, because this product's tokens obey a different and better law: a sheet
   that USES a token DECLARES it, since an unresolvable var() does not fall
   back to the old value, it voids the whole declaration. The press is declared
   in the three token authorities instead, and the sheets are held in agreement
   by a test. See editorial-frame.css for the reasoning behind the values. */

/* Button marks. One shared set (shell/icons.json), drawn in currentColor and
   sized in em, so a mark takes its button's own colour and size and an accent
   change recolours the product for free (spec R7). Universally understood
   marks only, per Ritu 2026-08-05: the conventional sign for each action and
   nothing clever. aria-hidden, because the button's words are the label. */
.ico {
  width: 1em;
  height: 1em;
  flex: none;
  display: inline-block;
  vertical-align: -0.125em;
  /* Teal by DEFAULT, not the button's ink. His reason for wanting marks at all
     was that they "will also lend some colour to the whole UI", and drawn in the
     label's dark ink they lend none. This is also the only teal on a tool with
     no option pills: IntroDoctor's panel is two selects, so its dash of teal
     comes from the marks on Check fidelity, Style pass, Copy and Export.
     Measured 2026-08-05 at 1440x900 with data-theme forced, by
     scripts/mark_contrast_check.mjs: --accent on --paper is 6.04:1 in day and
     6.83:1 on the cream masthead chrome, both past the 3:1 a graphical object
     needs (WCAG 1.4.11).

     THE OVERRIDE IS DECLARED BY WHOEVER PAINTS THE GROUND, not by a list here.
     A control that fills its own background sets `--ico-color: currentColor` in
     its OWN rule, so the mark follows that button's label. Ritu, 2026-08-05, of
     the teach page: "ADD TO MEMORY already has a vague logo. Just that it isn't
     visible in Night mode", then "the common defect is none of the logos are
     distinct against Navy." Both true, and it was six buttons, not one: on the
     navy pill the teal mark measured 2.04:1, and in NIGHT --cta-fill and
     --accent are the same #56B6BF, so the mark was drawn in the button's own
     fill at exactly 1:1.

     WHY A CUSTOM PROPERTY AND NOT A SELECTOR LIST. There WAS a list here — two
     selectors, `.toggle-btn.active .ico` and
     `.mode-switch button[aria-pressed="true"] .ico`. Probed against the rendered
     DOM across fifteen surfaces on 2026-08-05, both matched ZERO elements: the
     toggles carry `<span class="mark">`, not `.ico`, and the mode switch is
     text only. The mechanism had never once fired, which is precisely why the
     filled primaries shipped invisible. A list is also unable to express this
     codebase's shape: `.btn-save-settings` is --cta-fill in one rule and
     --accent-deep in another, and `.cta` is three different fills in three
     sheets. One class, three grounds. The declaration has to live with the
     paint. Guarded by tests/test_css_architecture.py so it stays culled. */
  color: var(--ico-color, var(--accent));
}
.ico svg { width: 100%; height: 100%; display: block; }
/* The anchor form matters: the masthead "Teach" is an <a>, and it took a mark on
   2026-08-05 because it sat as a bare word beside a marked gear. Without this it
   gets no gap and the mortarboard collides with the word. */
/* The label form joined on 2026-08-15: the Scroll Desk's Photo control is a
   <label> wrapping a hidden file input, and its new mark sat flush against
   the word for the same reason Teach's once did. */
button:has(> .ico),
a:has(> .ico),
label:has(> .ico) {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}
/* One glyph needs more than the shared 0.5em, and the reason is optical, not
   arithmetic. Every other mark in the set ends its ink in a stroke tip or a
   short arc with open space above and below it. The photo mark ends in a
   full-height vertical rule (rect x=2..14), which faces the P of PHOTO as a
   second stem and closes the gap to the eye at a spacing the ruler calls
   correct. Measured at 1440 in the rendered box: the drawn ink stops 1.01px
   inside the mark at 0.5em, against 1.69px for the speaker beside it, so the
   two controls in the same row were spaced differently while sharing a rule.
   0.62em puts the photo mark's ink gap at 9.0px and the speaker's at 8.2px,
   which is the order the shapes ask for.

   Ritu, 2026-08-17: "the logo for photo is almost sticking to the text". He was
   looking at prod, where this sheet had NO label rule at all and the mark sat
   flush against the word with zero gap. `photo` is used on exactly one control
   in the product (the Scroll Desk's Add material row), so this rule moves that
   button and nothing else; check with a grep for data-icon="photo". */
:is(button, a, label):has(> .ico[data-icon="photo"]) { gap: 0.62em; }
/* The action rows lay their buttons out themselves; the mark must not change
   how a row wraps, only what sits inside a button. */
.action-row button:has(> .ico),
.action-bar button:has(> .ico),
.fidelity-bar button:has(> .ico) { justify-content: center; }
