/* v005 | 2026-09-01 | 265 lines
 *
 * HappyShip design tokens.
 *
 * This file holds VALUES. brand/STYLE.md holds the rules that govern them —
 * what each token means and when it applies. Together the two are the source
 * of truth for HappyShip visual application on both surfaces. Neither defers
 * to any earlier brand document.
 *
 * Read by the website through the build.sh copy into web/site/brand/, and by
 * the application by reading it where it sits. Linked before styles.css.
 *
 * Two tiers:
 *   1. Palette and scales — global, identical everywhere.
 *   2. Environment layer — resolved per surface via [data-env] on <html>.
 *
 * Contrast ratios in comments are computed against the surface named. WCAG AA
 * needs 4.5:1 for normal text, 3:1 for text at 18.66px bold or 24px regular
 * and for UI component boundaries. Logotypes and disabled controls are exempt.
 */

:root {

  /* ---------------------------------------------------------------
     1. BRAND COLORS
     Four, and only four. A fifth brand color is not added to solve a
     contrast problem — the ramp and the tints below solve those.
     Semantic status colors (red, yellow, purple) are a separate set
     and are not defined yet.
     --------------------------------------------------------------- */

  --hs-navy:            #0A1D4D;  /* trust, control, headings, body text     */
  --hs-teal:            #12B8B0;  /* action, operations, client primary CTA  */
  --hs-teal-light:      #8CDED6;  /* supporting UI, internal band, selected  */
  --hs-orange:          #F9A11A;  /* accent, exceptions, value. Kept rare    */

  /* Deep navy is the dark field, not a fifth brand color. Website hero and
     footer only; the portals have no dark field. */
  --hs-navy-deep:       #071833;

  /* Navy-tinted lines, for use on dark fields only. On light surfaces the
     grey ramp supplies borders. */
  --hs-navy-line:       #16305A;  /* hairline divider on a dark field        */
  --hs-navy-line-heavy: #3C5C90;  /* visible border, e.g. outline button     */

  /* Teal hover. Lighter, so it is never used behind text. */
  --hs-teal-hover:      #15CFC6;

  /* ---------------------------------------------------------------
     2. GREY RAMP
     One cool ramp. Every grey in the system comes from here; a hex
     typed into a rule is a defect. Steps are spaced by role, not by
     an even lightness curve.
     --------------------------------------------------------------- */

  --hs-grey-50:   #F4F7FA;  /* page surface in both portals                  */
  --hs-grey-100:  #E9EEF7;  /* neutral badge fill, subtle block fill         */
  --hs-grey-200:  #DCE5EE;  /* borders, dividers, table rules, input edges   */
  --hs-grey-300:  #C6D2E4;  /* body text on a dark field — 11.57 on deep     */
  --hs-grey-400:  #94A7C4;  /* dim text on a dark field — 7.23 on deep       */
  --hs-grey-500:  #5F6E88;  /* muted text on light — 4.80 page, 5.16 white   */
  --hs-grey-700:  #4A5A75;  /* secondary text on light — 6.98 white          */
  --hs-grey-800:  #33415C;  /* body text on light — 9.52 page, 10.24 white   */

  --hs-white:     #FFFFFF;

  /* Disabled text on a dark field. Below 4.5:1 deliberately — WCAG exempts
     inactive controls, and a disabled item that reads as active is worse. */
  --hs-ink-disabled-dark: #5E7398;

  /* ---------------------------------------------------------------
     3. INK AND SURFACE ROLES
     Aliases onto the ramp. Prefer these in rules: they say what the
     color is for, so a ramp change lands everywhere it should.
     --------------------------------------------------------------- */

  --ink-strong:      var(--hs-navy);       /* headings, KPI numbers, figures */
  --ink-body:        var(--hs-grey-800);   /* paragraphs, table cells        */
  --ink-secondary:   var(--hs-grey-700);
  --ink-muted:       var(--hs-grey-500);   /* captions, helper, metadata     */
  --ink-on-dark:     var(--hs-grey-300);
  --ink-on-dark-dim: var(--hs-grey-400);
  --ink-inverse:     var(--hs-white);

  --surface-page:    var(--hs-grey-50);
  --surface-card:    var(--hs-white);
  --surface-sunken:  var(--hs-grey-100);
  --border-default:  var(--hs-grey-200);

  /* ---------------------------------------------------------------
     4. BADGE TINTS
     Derived from the brand colors, not new ones. Each pairs a fill
     with the one ink that passes on it.
     --------------------------------------------------------------- */

  --badge-positive-fill: var(--hs-teal-light);
  --badge-positive-ink:  #0A4F4B;            /* 6.06 on fill                 */
  --badge-attention-fill:#FFF1D9;
  --badge-attention-ink: #7A4B00;            /* 6.65 on fill                 */
  --badge-neutral-fill:  var(--hs-grey-100);
  --badge-neutral-ink:   var(--hs-grey-700); /* 5.99 on fill                 */

  /* ---------------------------------------------------------------
     5. TYPOGRAPHY
     Nunito Sans throughout. CJK codepoints fall through to Noto Sans
     HK — Hong Kong, not TC and not SC; they differ in glyph form for
     shared codepoints.
     --------------------------------------------------------------- */

  --font-brand: "Nunito Sans", Nunito, "Arial Rounded MT Bold", Arial, sans-serif;
  --font-cjk:   "Nunito Sans", "Noto Sans HK", "PingFang HK",
                "Hiragino Sans CNS", "Microsoft JhengHei", sans-serif;

  --fw-regular:    400;
  --fw-semibold:   600;
  --fw-bold:       700;
  --fw-extrabold:  800;

  /* CJK headings only. Noto Sans HK carries a real 900, so the weight is
     drawn rather than synthesized. Latin headings stop at --fw-extrabold. */
  --fw-black:      900;

  /* THE RAMP. Eleven steps, and every size in the system is one of them.
     Named by value, so a rule says what it renders and a step can be added
     later without renumbering the rest. A clamp() takes a step at BOTH
     ends: a floor is a size the interface actually renders, at the widths
     most people read it on, so it is a size like any other. */
  --fs-11:  11px;   /* badges and pills — the smallest type that ships     */
  --fs-13:  13px;   /* captions, metadata, fine print                      */
  --fs-14:  14px;   /* secondary UI — eyebrows, footer links               */
  --fs-15:  15px;   /* the working UI size: forms, buttons, table cells    */
  --fs-16:  16px;   /* body copy                                           */
  --fs-18:  18px;   /* lead paragraphs, card headings                      */
  --fs-20:  20px;   /* figures below KPI weight                            */
  --fs-24:  24px;   /* section and block headings                          */
  --fs-32:  32px;   /* KPI numbers                                         */
  --fs-40:  40px;   /* page headings                                       */
  --fs-52:  52px;   /* marketing display                                   */

  /* ROLES. Aliases onto the ramp, so a role can be re-pointed at another
     step without editing the rules that use it. Prefer the role in a rule
     wherever the role is clear; use the step where it is not, as a clamp
     end usually is. */
  --fs-caption:  var(--fs-13);
  --fs-ui:       var(--fs-15);
  --fs-body:     var(--fs-16);
  --fs-lead:     var(--fs-18);
  --fs-h3:       var(--fs-24);
  --fs-kpi:      var(--fs-32);   /* extrabold, tabular                     */
  --fs-h2:       var(--fs-40);
  --fs-display:  var(--fs-52);   /* extrabold                              */

  --lh-tight:  1.12;     /* headings                                         */
  --lh-body:   1.6;
  --lh-cjk:    1.8;      /* CJK needs more leading at the same size          */

  /* CJK headings only. --lh-cjk is BODY leading and is far too open for a
     heading; --lh-tight is too closed for CJK glyphs. This sits between. */
  --lh-cjk-heading: 1.35;

  --tracking-tight: -0.015em;  /* Latin headings only; zero for CJK          */

  /* ---------------------------------------------------------------
     6. SPACE, SHAPE, ELEVATION
     --------------------------------------------------------------- */

  --s1:  4px;
  --s2:  8px;
  --s3:  12px;
  --s4:  16px;   /* default component padding                               */
  --s5:  24px;   /* card and section internal spacing                       */
  --s6:  32px;
  --s8:  48px;   /* major layout separation                                 */

  --r-s:    8px;    /* tags, compact controls                               */
  --r-icon: 12px;   /* small filled tiles, e.g. the 44px service icons.      */
                    /* Not for controls — those take --r-m, which reads too  */
                    /* round at tile size.                                   */
  --r-m:    14px;   /* inputs, buttons                                      */
  --r-l:    20px;   /* cards, panels                                        */
  --r-pill: 999px;

  /* Borders and background contrast carry structure. Shadow is for floating
     surfaces only — menus, modals, and marketing cards that leave the page. */
  --shadow-card:   0 1px 2px rgba(10, 29, 77, 0.04);
  --shadow-float:  0 12px 32px rgba(10, 29, 77, 0.14);
  --shadow-raised: 0 24px 60px rgba(0, 0, 0, 0.36);  /* card on a dark field */

  /* Focus is orange in every environment. It is the only brand color that
     holds against all three bands and both page surfaces, and a ring whose
     color changes per environment is a ring someone fails to recognize. */
  --focus-color:  var(--hs-orange);
  --focus-width:  3px;
  --focus-offset: 3px;

  --control-min-height: 44px;   /* interactive target floor                  */

  /* ---------------------------------------------------------------
     7. ENVIRONMENT LAYER — DEFAULT: PUBLIC WEBSITE
     Selected by [data-env] on <html>. The website sets nothing and
     takes this block; the portals declare one attribute each. No
     runtime branching: the internal tool is a separate surface and
     sets its own attribute because of what it is, never because it
     inspected a session.
     --------------------------------------------------------------- */

  --env-page:        var(--hs-white);
  --env-band:        var(--hs-navy-deep);  /* nav and hero share the field   */
  --env-band-ink:    var(--ink-on-dark);
  --env-band-line:   var(--hs-navy-line);
  --env-card:        var(--hs-white);
  --env-action:      var(--hs-teal);
  --env-action-ink:  var(--hs-navy);       /* 6.57 on teal                   */
  --env-action-hover:var(--hs-teal-hover);

  /* The one exception in the system. The website hero CTA carries a white
     label on teal — 2.47:1, below AA. It is kept because the button sits on
     the deep navy field where the FILL reads at 7.17:1, so the control is
     unmistakable even where the label is not. It is scoped to that one
     control: no other button inherits it, whatever field it sits on, and
     every other label is --env-action-ink. STYLE.md §7 states the rule. */
  --hero-cta-ink: var(--hs-white);
}

/* -----------------------------------------------------------------
   CLIENT PORTAL — navy band on a grey page
   ----------------------------------------------------------------- */

[data-env="client"] {
  --env-page:        var(--surface-page);
  --env-band:        var(--hs-navy);
  --env-band-ink:    var(--ink-on-dark);   /* 10.60 on navy                  */
  --env-band-line:   var(--hs-navy-line);
  --env-card:        var(--hs-white);
  --env-action:      var(--hs-teal);
  --env-action-ink:  var(--hs-navy);       /* 6.57 on teal                   */
  --env-action-hover:var(--hs-teal-hover);
}

/* -----------------------------------------------------------------
   INTERNAL PORTAL — light teal band on a grey page
   The band separates from the page at 1.44:1, which is a hierarchy
   figure and not a contrast requirement: two adjacent decorative
   surfaces carry no WCAG minimum. STYLE.md §7 requires the lower
   edge rule that gives the band its definition.
   ----------------------------------------------------------------- */

[data-env="internal"] {
  --env-page:        var(--surface-page);
  --env-band:        var(--hs-teal-light);
  --env-band-ink:    var(--hs-navy);       /* 10.44 on light teal            */
  --env-band-line:   var(--border-default);
  --env-card:        var(--hs-white);
  --env-action:      var(--hs-navy);
  --env-action-ink:  var(--hs-white);      /* 16.21 on navy                  */
  --env-action-hover:#132A63;
}

/* -----------------------------------------------------------------
   REDUCED MOTION
   ----------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  :root { --motion-duration: 0s; }
}
