/* ============================================================================
   omnihub.css — the house sheet for omnihubcrm.app.

   Every value below is named after its FACTS.json key. There is no hard-coded
   colour, size or duration outside :root. If you need a value that is not here,
   you need a ruling, not a new number.

   INHERITANCE. Tokens are LaunchLocal's, unchanged — the ramp is lifted from
   the LaunchLocal site's house-sheet v2 so the two sites are the same system.
   The OmniHub-specific part is the GROUND SPLIT (FRESNEL GUIDELINES.md §1):

       chrome  = ink      header, nav, footer. Where the brand register lives.
       content = paper    the reading area.
       structure = blue   rules, frames, links. ON PAPER ONLY.
       accent  = orange   the active item. ONE per page.

   ⚠ CHROME EROSION is the named failure mode. Ink chrome gets "lightened for
   airiness" one component at a time and ends as blue-on-white, which is exactly
   what LaunchLocal's palette amendment exists to prevent. Do not lighten .chrome.
   ============================================================================ */

:root{
  /* --- palette.* (FACTS.json, inherited verbatim) --- */
  --ink:#1E1E1E;
  --paper:#FFFFFF;
  --blue:#0C65F5;              /* ON PAPER ONLY — 5.01:1. On ink it is 3.33:1 and fails. */
  --blue-light:#5A95F8;        /* ON INK ONLY — the only blue permitted there. */
  --signal-orange:#FB940F;     /* the lit thing. One per composition. */
  --ink-soft:#333333;
  --grey-on-paper:#6A6A73;
  --grey-on-ink:#8A94A3;
  --edge-subtle-on-ink:#33373E;
  --edge-subtle-on-paper:#E6E6E9;
  --edge-strong-on-ink:#6E7889;
  --edge-strong-on-paper:#6A6A73;
  --text-on-ink-floor:#7F8A99; /* holds against TRUE ink only — see the panel note below */

  /* --- palette._web_text_ramp (screen only) --- */
  --text-strong-on-ink:#F1F2F4;
  --text-body-on-ink:#C6CAD2;
  --text-muted-on-ink:#8A94A3;

  /* --- pane.edge_width_px --- */
  --pane-edge:1px;

  /* --- type.* --- */
  --font-display:'Archivo',system-ui,sans-serif;
  --font-text:'Inter',system-ui,sans-serif;

  --step-display:clamp(40px,11.2vw,180px);
  --step-huge:clamp(36px,8.6vw,112px);
  --step-page:clamp(30px,6.4vw,84px);
  --step-section:clamp(26px,4.6vw,40px);
  --step-subhead:clamp(19px,2.6vw,24px);
  --size-body:18px;
  --size-label:13px;
  --size-caption:14.5px;

  --w-display:700;
  --w-heading:600;
  --w-body:400;
  --w-label:600;

  --lh-display:0.94;
  --tr-display:-0.02em;
  --tr-heading:-0.022em;
  --tr-subhead:-0.015em;

  /* --- motion.specimens (inherited verbatim) --- */
  --dur-signal-dot:200ms;
  --dur-section-reveal:400ms;
  --dur-btn-hover:120ms;
  --dur-btn-press:80ms;
  --dur-link-underline:120ms;
  --dur-form-focus:120ms;
  --dur-nav:240ms;
  --ease-standard:cubic-bezier(0.2,0,0,1);

  /* --- layout --- */
  --shell:1180px;
  --gutter:clamp(20px,5vw,56px);
  --unit:22px;                 /* one body line-height = the clearance unit */
}

@media (prefers-reduced-motion:reduce){
  :root{
    --dur-signal-dot:0ms;--dur-section-reveal:0ms;--dur-btn-hover:0ms;
    --dur-btn-press:0ms;--dur-link-underline:0ms;--dur-form-focus:0ms;--dur-nav:0ms;
  }
}

/* ============================================================ reset + base */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-text);
  font-size:var(--size-body);
  font-weight:var(--w-body);
  line-height:calc(var(--unit) / var(--size-body) * 1em);
  -webkit-font-smoothing:antialiased;
}
img,svg,video{max-width:100%;height:auto;display:block}

/* Tabular figures. FACTS type.tabular_figures is MANDATORY on every number.
   ⚠ The `font:` shorthand silently resets font-variant-numeric. Never use it. */
.num,time,td,th,.price,.duration,.count{font-variant-numeric:tabular-nums}

h1,h2,h3{font-family:var(--font-display);margin:0}
h1{font-size:var(--step-page);font-weight:var(--w-display);line-height:var(--lh-display);letter-spacing:var(--tr-display)}
h2{font-size:var(--step-section);font-weight:var(--w-heading);letter-spacing:var(--tr-heading)}
h3{font-size:var(--step-subhead);font-weight:var(--w-heading);letter-spacing:var(--tr-subhead)}
p{margin:0 0 var(--unit)}
ul,ol{margin:0 0 var(--unit);padding-left:1.2em}

.shell{max-width:var(--shell);margin-inline:auto;padding-inline:var(--gutter)}
.label{font-size:var(--size-label);font-weight:var(--w-label);letter-spacing:.02em}
.caption{font-size:var(--size-caption);color:var(--grey-on-paper)}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* Links. On paper, blue. Underline grows from the left (motion 7). */
a{color:var(--blue);text-decoration:none;background-image:linear-gradient(currentColor,currentColor);
  background-size:0 1px;background-repeat:no-repeat;background-position:0 100%;
  transition:background-size var(--dur-link-underline) ease-out}
a:hover,a:focus-visible{background-size:100% 1px}
a:focus-visible{outline:var(--pane-edge) solid var(--blue);outline-offset:3px}

/* ============================================================ the pane
   The pane edge is the most-repeated brand element. CONSTANT WEIGHT, everywhere.
   Nothing crosses an edge. Content is inset from it. */
.pane{border:var(--pane-edge) solid var(--edge-subtle-on-paper);padding:calc(var(--unit) * 1.5)}
.on-ink .pane,.chrome .pane{border-color:var(--edge-subtle-on-ink)}

/* THE lit pane. orange_budget: ONE per page, never two, max 8% of the composition. */
.pane--lit{position:relative}
.pane--lit::before{
  content:"";position:absolute;left:calc(var(--pane-edge) * -1);top:0;bottom:0;width:3px;
  background:var(--signal-orange);
}
/* ⚠ orange on paper may ONLY be a bounded shape or a filled block — never text,
   never a 1px rule, never an icon stroke (FRESNEL GUIDELINES §1). The 3px bar
   above is a shape, and it sits on the pane edge, not in the text. */

/* ============================================================ ink surfaces */
.on-ink,.chrome{background:var(--ink);color:var(--text-body-on-ink)}
.on-ink h1,.on-ink h2,.on-ink h3,.chrome h1,.chrome h2{color:var(--text-strong-on-ink)}
.on-ink a,.chrome a{color:var(--blue-light)}
.on-ink .caption,.chrome .caption{color:var(--text-muted-on-ink)}
/* ⚠ --text-on-ink-floor (#7F8A99) is 4.76:1 against TRUE ink #1E1E1E ONLY. On any
   lifted panel it drops to ~4.43:1 and fails AA. Panels use --text-body-on-ink. */
.panel-on-ink{background:#232427;color:var(--text-body-on-ink)}

/* ============================================================ chrome
   ⚠ DO NOT LIGHTEN. See the chrome-erosion note at the top of this file. */
.chrome{border-bottom:var(--pane-edge) solid var(--edge-subtle-on-ink)}
.chrome__bar{display:flex;align-items:center;gap:var(--unit);
  padding-block:calc(var(--unit) * .8);flex-wrap:wrap}
.chrome__logo{display:block}
.chrome__logo img{height:32px;width:auto}   /* lockup minimum is 120px wide */
.chrome__nav{margin-left:auto;display:flex;align-items:center;gap:calc(var(--unit) * 1.2)}
.chrome__nav a{font-size:var(--size-label);font-weight:var(--w-label)}
.chrome__nav a[aria-current="page"]{color:var(--text-strong-on-ink)}
.site-footer{border-top:var(--pane-edge) solid var(--edge-subtle-on-ink);
  padding-block:calc(var(--unit) * 2);font-size:var(--size-caption)}
.site-footer nav{display:flex;flex-wrap:wrap;gap:var(--unit);margin-bottom:var(--unit)}

/* ============================================================ buttons
   Motion 4: hover is COLOUR ONLY — background blue -> blue_light AND the label
   paper -> ink. Paper on blue_light is 2.96:1 and fails; ink on blue_light is
   5.63:1, which is a pair the book already approves. No lift, no shadow, no scale. */
.btn{
  display:inline-block;font-family:var(--font-text);font-size:var(--size-body);
  font-weight:var(--w-label);line-height:1.2;padding:.7em 1.3em;border:var(--pane-edge) solid var(--blue);
  background:var(--blue);color:var(--paper);cursor:pointer;background-image:none;
  transition:background-color var(--dur-btn-hover) ease-out,color var(--dur-btn-hover) ease-out;
}
.btn:hover{background:var(--blue-light);border-color:var(--blue-light);color:var(--ink)}
.btn:active{background:var(--blue);border-color:var(--blue);color:var(--paper)}
.btn:focus-visible{outline:var(--pane-edge) solid var(--blue-light);outline-offset:3px}
.btn--ghost{background:transparent;color:var(--blue);}
.on-ink .btn--ghost,.chrome .btn--ghost{color:var(--blue-light);border-color:var(--edge-strong-on-ink)}
.btn--block{display:block;width:100%;text-align:center}

/* ============================================================ forms
   Motion 8: focus steps the pane edge to blue, WEIGHT UNCHANGED. The edge never
   thickens — constant pane-edge weight is a brand law and does not get suspended
   for a state change.
   ERRORS CARRY NO COLOUR (FACTS palette._error_state): the edge steps
   edge_subtle -> edge_strong, plus a message. No red. No orange. */
.field{margin-bottom:var(--unit)}
.field label{display:block;font-size:var(--size-label);font-weight:var(--w-label);
  margin-bottom:calc(var(--unit) * .35)}
.field input[type=email],.field input[type=password],.field input[type=text]{
  width:100%;font-family:var(--font-text);font-size:var(--size-body);
  padding:.65em .8em;background:transparent;color:inherit;
  border:var(--pane-edge) solid var(--edge-subtle-on-ink);
  transition:border-color var(--dur-form-focus) ease-out;
}
.field input:focus{outline:none;border-color:var(--blue-light)}
.field[data-error] input{border-color:var(--edge-strong-on-ink)}
.field__error{display:none;font-size:var(--size-caption);color:var(--text-strong-on-ink);
  margin-top:calc(var(--unit) * .3)}
.field[data-error] .field__error{display:block}
.field--check{display:flex;align-items:center;gap:.6em;font-size:var(--size-caption)}
.field--check label{margin:0;font-weight:var(--w-body)}

/* ============================================================ video pane */
.video{border:var(--pane-edge) solid var(--edge-subtle-on-paper);background:var(--ink)}
.video__frame{position:relative;aspect-ratio:16/9}
.video__frame video,.video__frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.video__meta{display:flex;gap:var(--unit);padding:calc(var(--unit) * .7) calc(var(--unit) * 1);
  font-size:var(--size-caption);color:var(--text-muted-on-ink);border-top:var(--pane-edge) solid var(--edge-subtle-on-ink)}

/* ============================================================ rhythm */
.section{padding-block:calc(var(--unit) * 3)}
.section__kicker{font-size:var(--size-label);font-weight:var(--w-label);
  color:var(--grey-on-paper);margin-bottom:calc(var(--unit) * .5)}
.on-ink .section__kicker{color:var(--text-muted-on-ink)}
.grid{display:grid;gap:var(--unit)}
@media (min-width:760px){
  .grid--3{grid-template-columns:repeat(3,1fr)}
  .grid--2{grid-template-columns:repeat(2,1fr)}
}
.steps{list-style:none;padding:0;counter-reset:step}
.steps li{counter-increment:step;display:grid;grid-template-columns:2.2em 1fr;
  gap:var(--unit);padding-block:calc(var(--unit) * .6);
  border-top:var(--pane-edge) solid var(--edge-subtle-on-paper)}
.steps li::before{content:counter(step);font-family:var(--font-display);
  font-weight:var(--w-heading);font-variant-numeric:tabular-nums;color:var(--blue)}

/* Section reveal — motion 3: opacity + 8px, never a slide. */
@media (prefers-reduced-motion:no-preference){
  .reveal{opacity:0;transform:translateY(8px);
    transition:opacity var(--dur-section-reveal) var(--ease-standard),
               transform var(--dur-section-reveal) var(--ease-standard)}
  .reveal.is-in{opacity:1;transform:none}
}
