/* ToolForge design-system reference — the layer the handoff has no place for.
 *
 * Two jobs, and the file keeps its name because the first one is why it exists:
 *   1. MOBILE. The Claude Design handoff is a fixed 1440px canvas built entirely from INLINE
 *      styles and it ships zero media queries. On a phone it held a hard 792px floor and
 *      scrolled sideways, cutting text off both edges.
 *   2. ORPHAN CONTROL. Line breaking is a function of width, so it has no home in a
 *      fixed-canvas design file at all. That section sits OUTSIDE every media query, because
 *      the sweep found stranded words up to 1024px — not only on phones.
 *
 * Why every rule carries !important: an inline style beats any stylesheet rule except an
 * !important one. There is no second !important system on this page to fight with — the
 * handoff has none — so this is one layer overriding static inline styles, not the
 * two-systems-in-conflict pattern retired from greenvault2 on 2026-08-05.
 *
 * Why the selectors match on `style` substrings: the handoff gives no element a class, an
 * id, or a data attribute. Matching on the serialized inline style is the only stable hook.
 * Verified against the rendered DOM 2026-08-07: React serializes every declaration as
 * `prop: value;` — one space after the colon, a trailing semicolon on the last declaration
 * too — so `[style*="padding: 44px;"]` matches the single-value shorthand and NOT
 * `padding: 44px 48px`. `_import_design.py` asserts the counts these rules depend on, so a
 * change to the design fails the import loudly instead of silently unhooking this file.
 *
 * Nothing here changes a colour, a weight, a border, or a spacing token. It changes only
 * what the handoff never specified: behaviour below its own canvas width.
 */

html { -webkit-text-size-adjust: 100%; }

/* ============================================================ orphan control — ALL widths
 *
 * An orphan is one word alone on the last line. It is a function of WIDTH, not of
 * breakpoint: `orphan_sweep.cjs` measures line boxes at 360/390/412/430/768/1024/1280/1440
 * and found stranded words at every width from 1024 down. So these rules sit outside the
 * media queries — a fix that only applies below 900px is a fix for the wrong widths.
 *
 * 412 is the width that matters most here and the one that is easiest to miss: the phone
 * screenshot that opened this task was 1080px wide, which is 412 CSS px at DPR 2.625.
 */

/* T1. Display type gets `balance`, which evens the line lengths of short headings. This is
 *     the reliable layer. It cleared `Status — badges, alerts, toast`, `Disclosure, steps,
 *     timeline, lists`, `Inputs — search, chips, upload, date` and the 56px hero. Browsers
 *     cap `balance` at a few lines, which is exactly why it belongs on headings only.
 *     Attribute selectors outrank the bare element selectors in T2, so balance wins where
 *     both apply — no !important needed between the two. */
body [style*="font-size: 56px"], body [style*="font-size: 44px"],
body [style*="font-size: 42px"], body [style*="font-size: 40px"],
body [style*="font-size: 30px"], body [style*="font-size: 28px"],
body [style*="font-size: 24px"] { text-wrap: balance; }

/* T2. Running prose gets `pretty`, which reduces last-line raggedness.
 *     🔴 `pretty` IMPROVES the odds and guarantees nothing — it makes no promise about word
 *     count, and stopping here and calling orphans fixed would be reporting an assumption.
 *     `orphan_sweep.cjs` is what decides whether it was enough, at every swept width. */
body div, body p, body span, body a, body label, body li { text-wrap: pretty; }

/* ============================================================ tablet and below */
@media (max-width: 900px) {

  /* 1. The page frame. 48px of side padding costs a quarter of a phone screen. */
  [style*="padding: 56px 48px 120px;"] {
    padding: 32px 20px 72px !important;
    gap: 48px !important;
  }

  /* 2. Nothing may be wider than its parent, and every box may shrink below its own
   *    content. Together these two lines retire every fixed width on the page —
   *    520px toast, 340px drawer, 260px sidebar, 240px dropdown, 220px rule sample. */
  body div, body section, body header, body span, body a, body label, body p,
  body button, body input, body select, body textarea, body svg {
    max-width: 100% !important;
    min-width: 0 !important;
  }

  /* 2b. The handoff never sets box-sizing, so the whole page is content-box. Combined with
   *     rule 2 that overflows every padded card by EXACTLY its padding plus its border.
   *     Measured in WebKit at 390px before this rule: a card inside a 350px column came out
   *     388px wide — 350 content + 18 + 18 padding + 1 + 1 border — and every one of the
   *     seven failing iPhones failed by that same arithmetic. `max-width: 100%` has to cap
   *     the BORDER box, and every rule below assumes it does. */
  body div, body section, body header, body span, body a, body label, body p,
  body button, body input, body select, body textarea {
    box-sizing: border-box !important;
  }

  /* 3. Every flex row wraps. This is what releases the 792px floor: the page header is a
   *    space-between row holding a 392px non-wrapping pillar strip. */
  body [style*="display: flex"] { flex-wrap: wrap !important; }

  /* 3b. `flex: 1` computes to `flex: 1 1 0%` — a flex BASIS of zero. A zero-basis item can
   *     never make its line overflow, so it never triggers the wrap in rule 3; it just gets
   *     squeezed instead. The nav demo puts a 260px fixed sidebar beside one: measured at
   *     390px the panel stayed on the same line at 68px wide and its contents spilled out.
   *     A real basis makes the line genuinely overflow, so it wraps. This rule must sit
   *     AFTER rule 2 — same specificity, so source order decides the min-width winner. */
  body [style*="flex: 1 1 0%"] { flex-basis: 300px !important; min-width: 200px !important; }

  /* 4. Multi-column grids drop to two. Two exceptions, both excluded by value:
   *    repeat(7,1fr) is the date picker — seven columns IS the calendar;
   *    2.2fr … is the data table, handled in rule 5. */
  body [style*="grid-template-columns"]:not([style*="repeat(7"]):not([style*="2.2fr"]) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  body [style*="grid-column: span 2"] { grid-column: auto !important; }

  /* 5. The data table keeps its five columns and scrolls INSIDE its own box, so it never
   *    pushes the page sideways. A stacked table loses the head-to-cell alignment that
   *    makes it a table. */
  body div:has(> [style*="2.2fr"]) { overflow-x: auto !important; }
  body [style*="2.2fr"] { min-width: 620px !important; }

  /* 6. The top bar sets height:76px. Once its row wraps, a fixed height clips it. */
  body [style*="height: 76px;"] { height: auto !important; padding: 14px 16px !important; }

  /* 7. Canvas-scale padding on the large blocks. Longest match last — equal specificity,
   *    so source order decides the winner. */
  body [style*="padding: 44px;"]          { padding: 20px !important; }
  body [style*="padding: 40px;"]          { padding: 20px !important; }
  body [style*="padding: 30px;"]          { padding: 22px !important; }
  body [style*="padding: 28px;"]          { padding: 20px !important; }
  body [style*="padding: 26px;"]          { padding: 20px !important; }
  body [style*="padding: 32px 44px;"]     { padding: 22px 18px !important; }
  body [style*="padding: 36px 44px;"]     { padding: 22px 18px !important; }
  body [style*="padding: 40px 44px;"]     { padding: 22px 18px !important; }
  body [style*="padding: 48px 44px;"]     { padding: 32px 20px !important; }
  body [style*="padding: 44px 48px;"]     { padding: 28px 20px !important; }
  body [style*="padding: 72px 64px;"]     { padding: 40px 20px !important; }
  body [style*="padding: 28px 32px 0px;"] { padding: 22px 20px 0 !important; }
  body [style*="padding: 26px 32px 28px;"]{ padding: 20px !important; }
  body [style*="padding: 36px 28px;"]     { padding: 24px 18px !important; }
}

/* ============================================================ phone */
@media (max-width: 620px) {

  /* 8. One column. Still excluding the calendar and the table. */
  body [style*="grid-template-columns"]:not([style*="repeat(7"]):not([style*="2.2fr"]) {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* 9. The type-spec gutter is a fixed 150px column beside each sample. At phone width it
   *    takes half the screen and squeezes the sample into a two-word rag. Full width turns
   *    it into a label ABOVE its sample, which is what the wrap in rule 3 then does. */
  body [style*="width: 150px;"] { width: 100% !important; }

  /* 10. Cap the display sizes. The scale itself is unchanged — section 02 still SAYS
   *     56 / 40 / 28, and says it at a size a phone can render. */
  body [style*="font-size: 56px"] { font-size: 34px !important; }
  body [style*="font-size: 44px"] { font-size: 32px !important; }
  body [style*="font-size: 42px"] { font-size: 30px !important; }
  body [style*="font-size: 40px"] { font-size: 28px !important; }
  body [style*="font-size: 30px"] { font-size: 25px !important; }
  body [style*="font-size: 28px"] { font-size: 24px !important; }
  body [style*="font-size: 24px"] { font-size: 21px !important; }

  /* 11. Mono lines do not break at spaces the way prose does — one long command or error
   *     string is a single unbreakable run wider than the screen. */
  body [style*="Geist Mono"] { overflow-wrap: anywhere !important; }
}

/* ============================================================ separator strips
 *
 * THE DEFECT IN THE 2026-08-07 SCREENSHOT. The pillar strip is seven flex children —
 * [ANALYTICS][|][APPLICATIONS][|][AUTOMATION][|][AGENTICS] — and rule 3 above makes every
 * flex row wrap. So it broke after the third separator:
 *
 *     ANALYTICS | APPLICATIONS | AUTOMATION |          <- separator dangling at the end
 *     AGENTICS                                          <- stranded alone
 *
 * A text-node orphan walk cannot see this. Every child is its own single-word element, so
 * each one measures as perfectly wrapped; only measuring the CONTAINER finds it. That is
 * why `orphan_sweep.cjs` carries a second detector, and the first thing that detector did
 * was reproduce this exact case at 360, 390, 412 and 430.
 *
 * Measured at 412px: header strip natural width 392px in a 372px box; footer strip 410px in
 * a 332px box. The header fits once the viewport passes ~432px and the footer at ~490px, so
 * 500px is the breakpoint that covers both with a margin. Above it the strip sits on one
 * line and none of this applies.
 */
@media (max-width: 500px) {

  /* 12. Both pillar strips become a deliberate 2x2 with the middle separator removed:
   *
   *         ANALYTICS  |  APPLICATIONS
   *         AUTOMATION |  AGENTICS
   *
   *     Three auto columns and seven children would put the fourth child (the middle `|`)
   *     at the start of row two, so it is hidden rather than left to open a line. Nothing
   *     is deleted from the document — the pillars still read in order, and the separator
   *     between line 1 and line 2 is the line break itself.
   *
   *     The selector is verified against the rendered DOM, not assumed: this pair of
   *     substrings matches exactly 2 elements, the header strip and the footer strip. The
   *     only other element carrying `letter-spacing: 0.11em` at 13px is the `READ MORE ->`
   *     link, which is an <a>, so the `div` qualifier excludes it. */
  body div[style*="font-size: 13px"][style*="letter-spacing: 0.11em"] {
    display: grid !important;
    grid-template-columns: auto auto auto !important;
    justify-content: start !important;
    align-items: center !important;
    row-gap: 6px !important;
  }
  body div[style*="font-size: 13px"][style*="letter-spacing: 0.11em"] > :nth-child(4) {
    display: none !important;
  }

  /* 13. The breadcrumb `WORKSPACE / PIPELINES / DAILY_REVENUE` is the same disease in a
   *     milder form: 5 children, 286px of content, and at 360px a 270px box. It overflows
   *     by 16px and wraps, leaving a `/` at the end of the line. It does not need a second
   *     row — it needs 16px. Dropping the gap from 10px to 4px across four gaps returns
   *     24px, so the whole trail stays on one line and no separator can end it. */
  body div[style*="font-size: 12px"][style*="letter-spacing: 0.12em"] {
    gap: 4px !important;
  }
}
