/* obi-web.css — the web layer for Karl's Obi design system in Ovation.
   Spec: plans/WEB-EXTENSIONS.md in William's Ovation folder (outside this repo).
   Files under obi/ are Karl's handoff, unedited. Never edit them; override here. */

/* 1. Obi in a low-priority cascade layer. Any app rule outranks Obi's base defaults, and Obi's
      *:focus-visible{border-radius:4px} no longer reshapes focused controls (measured 2026-09-23). */
@import url("obi/styles.css") layer(obi);

/* 2. Obi bug: --text-body is declared as a colour and again as 17px; the size wins, so Obi's own
      body{color:var(--text-body)} fails and text renders black. Never use --text-body as a colour. */
body { color: var(--ink); }

/* 3. Type on Obi's scale (Pass 3, WEB-EXTENSIONS §15.1). The Pass 1 holdover (16px / 1.45) is gone: the body is
      Obi's own 17px / 1.55, from Obi's base. Obi's type sizes are restated here in rem, the same pixels at the
      browser's default 16px, so every size follows the reader's own text-size setting (owner ruling R26,
      plans/DURABILITY.md; WCAG 1.4.4). Nothing is set below --text-caption. */
:root {
  --text-display: 2.5rem; --text-h1: 2rem; --text-h2: 1.625rem; --text-h3: 1.3125rem;
  --text-body-lg: 1.1875rem; --text-body: 1.0625rem; --text-label: .9375rem; --text-caption: .8125rem;
}
h1 { font-size: var(--text-h2); line-height: var(--lh-h2); margin: 0 0 var(--space-2); } /* a view title */
/* §15.3: margins the browser computes from em become Obi steps; :where() keeps every module rule ahead of these. */
:where(p) { margin: 0 0 var(--space-3); }
:where(ul, ol) { margin: 0 0 var(--space-3); padding-left: var(--space-5); }
:where(h4, h5, h6) { margin: 0 0 var(--space-2); }
/* §15.3: the one compact density (the switch in Settings sets body.ov-compact). Rows that hold only text drop to
   --control-dense; rows that hold a control keep --row-dense; text sizes never change with density. */
body.ov-compact.ov-shelled { --ov-pady: var(--space-4); }
body.ov-compact .card { padding: var(--space-4); }
body.ov-compact :is(td, th) { height: var(--control-dense); padding-block: var(--space-1); }
body.ov-compact :is(td, th):has(input, select, button) { height: var(--row-dense); }
body.ov-compact .ov-tile { min-height: var(--control-dense); }

/* 4. Foundations. */
:root {
  color-scheme: light;                 /* Obi has no dark mode */
  accent-color: var(--accent-primary);
  --on-accent: var(--apricot-ink);     /* text on the primary fill: Obi's Button pairing */
  /* WEB-EXTENSIONS §3 (amended for Pass 2: navigation rows and pills as well as grids) */
  --row-dense: 40px;                   /* a navigation row: rail destination, menu item */
  --control-dense: var(--space-6);     /* 32px: a mode pill, a header button */
}

/* 4a. The skip link (WEB-EXTENSIONS §14.12): hidden until focused, then top left in the secondary Button look. */
.ov-skip { position: absolute; left: var(--space-3); top: var(--space-3); z-index: 500; transform: translateY(-200%);
  background: var(--surface); color: var(--ink); border: 1px solid var(--line-strong); border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-4); font-weight: var(--fw-semibold); text-decoration: none; box-shadow: var(--elev-2);
  max-width: calc(100vw - 2 * var(--space-3)); overflow-wrap: anywhere; } /* stays on screen in the narrowest window (R26) */
.ov-skip:focus, .ov-skip:focus-visible { transform: none; }

/* 4b. Pass 4 (WEB-EXTENSIONS §16): text for assistive technology only, and a real <button> that looks exactly like
       the element it replaced (a clickable card, row or chip), keeping Obi's focus ring. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.ov-plain { appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit;
  text-align: inherit; line-height: inherit; letter-spacing: inherit; cursor: pointer; }

/* 4c. Amendment to Obi, R24 (WEB-EXTENSIONS §16.3 row 20; the local Obi copy's base.css and AMENDMENTS.md): Obi's
       *:focus-visible adds border-radius:4px, which reshapes a focused element that has no radius of its own (the
       wordmark, a text link). Focus keeps each element's own shape: in a layer above Obi's, the radius reverts, and
       Obi's 2px ring and offset stay. The app's own radii are unlayered and unaffected. */
@layer obi-r24 { *:focus-visible { border-radius: revert; } }

/* 5. Scrollbars (WEB-EXTENSIONS §5): 12px with a 2px transparent border leaves an 8px warm-grey thumb. */
html { scrollbar-width: thin; scrollbar-color: var(--text-muted) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-thumb { background: var(--text-muted); border-radius: var(--radius-pill);
  border: 2px solid transparent; background-clip: content-box; }

/* 6. kbd (WEB-EXTENSIONS §5), for the Ctrl/Cmd-K hint. */
kbd { background: var(--surface-raised); border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 2px var(--space-1); font-size: var(--text-caption); }

/* 7. Forced colours (WEB-EXTENSIONS §8), bound to this app's classes. In Windows High Contrast every fill
      becomes a system colour: the seven CAPS levels would collapse into one, and the button hierarchy
      would flatten. */
@media (forced-colors: active) {
  :focus-visible { outline-color: Highlight; }
  .lvl1, .lvl2, .lvl3, .lvl4, .lvl5, .lvl6, .lvl7, .code-btn.on { forced-color-adjust: none; }
  .btn { background: ButtonText; color: ButtonFace; border: 1px solid ButtonText; }
  /* Filled buttons opt out: the browser otherwise paints a Canvas-coloured backplate behind the label, and a
     ButtonFace label on that backplate cannot be seen (measured 2026-09-23). Their colours stay system colours.
     The secondary (ghost) button keeps the browser's forcing, so its text always follows the user's theme. */
  .btn:not(.ghost) { forced-color-adjust: none; }
  .btn.ghost { background: ButtonFace; color: ButtonText; border: 1px solid ButtonText; }
  .btn:disabled { background: ButtonFace; color: GrayText; border-color: GrayText; }
  .danger, nav.tabs button.active, .ov-tile.on { forced-color-adjust: none; }
  /* Pass 2 (WEB-EXTENSIONS §14.12): where you are still reads. The lit destination, the current mode and Capture opt
     out of forcing, as the filled buttons do, and take system colours; lock icons draw in currentColor, so they stay. */
  .ov-tile.on, .ov-mode[aria-current="page"] { background: Highlight; color: HighlightText; border-color: Highlight; }
  .ov-mode[aria-current="page"], .ov-capture { forced-color-adjust: none; }
  .ov-capture { background: ButtonText; color: ButtonFace; border: 1px solid ButtonText; }
  .ov-capture[aria-current="page"] { background: Highlight; color: HighlightText; }
}

/* 8. Print (WEB-EXTENSIONS §7), in addition to the app's own print block in ovation.css.
      A4 is stated; the 16mm @page margin is not, because with it the Reports parent summary grew from one
      page to two (measured 2026-09-23), so the browser's default margin stays. */
@page { size: A4 portrait; }
@media print {
  #reportArea :is(.notes, .ev-summary, .hq-kpi, .bl-stat) { background: none; }
  /* Pass 2: navigation never prints (WEB-EXTENSIONS §14.12) */
  #ovModes, #ovFabs, #ovCapture, .ov-skip, #ovAcctMenu, #ovAcct { display: none !important; }
  #ovMain { padding-bottom: 0; }
  .lvl1, .lvl2, .lvl3, .lvl4, .lvl5, .lvl6, .lvl7 { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* 9. Amendments to Obi, R24 (WEB-EXTENSIONS §16.2 and §16.3; owner rulings R24 and R25). The same values as
      William's local Obi copy (C:\Synqa Projects\Design Systems\obi-design-system\, AMENDMENTS.md A1 to A12);
      Karl's files and obi/ stay verbatim. Obi's tokens and base rules are amended in the obi-r24 layer (above
      Obi's layer, below every app rule, as 4c's focus amendment); the app's own properties and rules that use
      them follow, unlayered. Ratios are WCAG 2.x contrast, Karl's value -> the amended value.
      Paste after section 8 (it must come after section 4, whose --on-accent and accent-color it replaces). */
@layer obi-r24 {
  :root {
    /* A1 amends Obi --text-muted (Karl: var(--warm-grey) #8C8577). Warm-grey darkened, OKLCH lightness only.
       bone 3.43->5.65, cream 3.60->5.94, sand 3.11->5.13, the tints 2.81-3.17 -> 4.63-5.23,
       --line and the pressed fill #EAE1CF 2.76/2.82 -> 4.55/4.65. Warm-grey itself stays (icons, lines, 3:1). */
    --text-muted: #696255;
    /* A2 beside Obi --apricot-ink (#7A3A11): the primary Button label. --caps-3-ink (#4A1E00, Obi's ink for this
       very fill) darkened: apricot 3.21->6.43, hover #DA762C 2.71->5.42, pressed #C96A26 2.28->4.57. */
    --apricot-ink-strong: #370D00;
    /* A3 beside Obi --clay (#B5573A): clay as text (links, concern labels); the clay fill stays.
       bone 4.48->5.59, cream 4.71->5.88, sand 4.07->5.08, clay-tint 3.67->4.58. */
    --clay-text: #A4472B;
    /* A4 beside Obi --success (#3E7D52): success as text; the fill stays.
       bone 4.61->5.24, cream 4.85->5.51, sand 4.19->4.77, success-tint 4.03->4.58. */
    --success-text: #35744A;
    /* A5 amends Obi --caps-2-ink (Karl: #FFFFFF) on --caps-2 #CB6C36: 3.66->4.60 (--ink itself is 4.498). */
    --caps-2-ink: #221C18;
    /* A6 amends Obi --caps-6-ink (Karl: #1F3D28) on --caps-6 #6FA06B: 3.94->4.60. */
    --caps-6-ink: #14321E;
    /* A7 amends Obi --sage-ink (Karl: #1F3D28) on --sage #5E9C6F: 3.68->4.58; on sage-tint 9.91->12.34. */
    --sage-ink: #0F2D19;
    /* A12 beside Obi --sky-ink (#13334C, which stays for text on the sky tint): text ON the sky fill.
       sky #4E86B4 3.36->4.56 (white on sky is 3.89). */
    --sky-ink-strong: #001931;
  }
  /* A8 amends Obi's base a{color:var(--clay)}: sand 4.07->5.08, bone 4.48->5.59, cream 4.71->5.88.
     Links in running text keep Obi's underline (the darker clay is 2.8:1 from body text, WCAG 1.4.1). */
  a { color: var(--clay-text); }
  /* A9 amends Obi's base a:hover{color:var(--apricot)}: bone 2.50->8.05, cream 2.63->8.46, sand 2.28->7.32. */
  a:hover { color: var(--apricot-ink); }
}

:root {
  /* The app's primary label (section 4 set var(--apricot-ink)): A2's value, 3.21->6.43 at rest. */
  --on-accent: var(--apricot-ink-strong);
  /* §16.3 #8: native checkbox, radio and range accent. Apricot 2.63 on cream -> --caps-2 (Obi's control-accent
     step of the same ramp) cream 3.60, bone 3.43, sand 3.11. */
  accent-color: var(--caps-2);
  /* The app's muted text before ovation-theme.js runs (ovation.css :root still says var(--warm-grey); the
     theme's apply() now writes var(--text-muted) inline too). */
  --muted-dim: var(--text-muted);
}

/* Section 5's scrollbar thumb stays warm-grey (WEB-EXTENSIONS §5; 3:1 is enough for it): it read --text-muted,
   which A1 now darkens for text. (Equivalent: change section 5's two var(--text-muted) to var(--warm-grey).) */
html { scrollbar-color: var(--warm-grey) transparent; }
::-webkit-scrollbar-thumb { background-color: var(--warm-grey); } /* longhand: keeps section 5's content-box clip */

/* §16.3 #12: the current rail destination was marked only by the apricot fill, 2.50:1 against the page. A 2px
   --apricot-ink edge (1px border and 1px inset shadow, so nothing moves), as the current mode pill has: bone 8.05,
   and 3.2:1 against the apricot fill inside it. Forced colours keep section 7's Highlight. */
@media (forced-colors: none) {
  .ov-tile.on, .ov-tile.on:hover, .ov-tile.on:active,
  /* 4.V: O'Chat's view toggles (Chats, Directory, Moderation, Rules) mark the current one the same way */
  .oc-sub .btn[aria-current="true"], .oc-sub .btn[aria-current="true"]:hover, .oc-sub .btn[aria-current="true"]:active {
    border-color: var(--apricot-ink); box-shadow: inset 0 0 0 1px var(--apricot-ink);
  }
}
