/* Owner-approved neutral reading surfaces with warm brand/ink (2026-10-06).
   Explicit roles keep financial status and module-specific content colors intact. */
:root {
  --hx-theme-deep: #392e27;
  --hx-theme-deep-rgb: 57 46 39;
  --hx-theme-portal-tint: #30261f;
  --hx-theme-portal-tint-rgb: 48 38 31;
  --hx-theme-photo-shade: #392e27;
  --hx-theme-paper: #f7f7f7;
  --hx-theme-paper-rgb: 247 247 247;
  --hx-theme-surface: #ffffff;
  --hx-theme-ink: #342b25;
  --hx-theme-muted: #716356;
  --hx-theme-line: #d9d9d9;
  --hx-theme-control-border: #95816b;
  --hx-theme-link: #805b3b;
  --hx-theme-selected-bg: #e9e9e9;
  --hx-theme-selected-ink: #65482f;
  --hx-theme-on-deep: #fbf6eb;
  --hx-theme-on-deep-muted: #ddd0ba;
  --hx-theme-on-deep-link: #ead1a5;
  --hx-theme-on-primary: #fff;
}

/* Hanetic Design System — tokens.css (Phase 1)
   ------------------------------------------------------------------
   Single source of truth for color, type, spacing, radius, motion and
   layout tokens. All variables are namespaced `--hx-*` so this file can
   be loaded on legacy pages (Finance/Travel still on styles.css) without
   colliding with the legacy `:root` variables (--bg, --text, ...).

   Breakpoint contract (media queries cannot use vars; keep these values):
     - phone            (max-width: 760px)
     - tablet           (min-width: 761px) and (max-width: 1180px)
     - desktop          (min-width: 1181px)
     - short landscape  (orientation: landscape) and (max-height: 560px)
   Apple safe-area is first-class: sticky/fixed offsets must derive from
   --hx-shell-top / env(safe-area-inset-*) — never raw top: 0/10px. */

:root {
  /* ---- Ink & surfaces (light context) ---- */
  --hx-ink: #101716;
  --hx-ink-soft: rgba(16, 23, 22, 0.66);
  --hx-ink-faint: rgba(16, 23, 22, 0.45);
  --hx-bg: #f4f8f7;
  --hx-surface: rgba(255, 255, 255, 0.72);
  --hx-surface-strong: rgba(255, 255, 255, 0.88);
  --hx-line: rgba(16, 23, 22, 0.08);
  --hx-line-strong: rgba(16, 23, 22, 0.13);

  /* ---- Ink & surfaces (dark context: portal photo, cars garage) ---- */
  --hx-dark-ink: #f4f7f5;
  --hx-dark-ink-soft: rgba(244, 247, 245, 0.72);
  --hx-dark-ink-faint: rgba(244, 247, 245, 0.48);
  --hx-dark-surface: rgba(255, 255, 255, 0.12);
  --hx-dark-surface-strong: rgba(5, 14, 15, 0.78);
  --hx-dark-line: rgba(255, 255, 255, 0.18);
  --hx-dark-line-soft: rgba(255, 255, 255, 0.1);

  /* ---- Dark glass surfaces (Phase M0) --------------------------------
     Canonical white-alpha steps for glass cards on dark pages. Every
     theme hand-copied its own rgba(255,255,255,0.0x) before M0; new dark
     glass MUST use these four steps, and existing themes migrate
     opportunistically during their M1+ motion pass (values below match
     the most common hand-copied ones exactly, so adoption is a pure
     var() swap with zero visual change). Deliberate outliers (e.g.
     portal's 0.12 = --hx-dark-surface) stay on their own token/literal. */
  --hx-glass-bg-faint: rgba(255, 255, 255, 0.045);
  --hx-glass-bg: rgba(255, 255, 255, 0.05);
  --hx-glass-bg-soft: rgba(255, 255, 255, 0.06);
  --hx-glass-bg-strong: rgba(255, 255, 255, 0.08);
  /* Card-level backdrop blur; --hx-blur (below) stays the heavier
     shell/hero variant. */
  --hx-blur-card: blur(18px) saturate(1.1);

  /* ---- Brand & status ---- */
  --hx-accent: #2f8b65;
  --hx-accent-2: #6dd6b2;
  --hx-accent-soft: rgba(47, 139, 101, 0.12);
  --hx-pass: #2f8b65;
  --hx-warn: #b77a18;
  --hx-fail: #c84d4d;
  --hx-info: #2b6387;

  /* ---- Typography ---- */
  --hx-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Noto Sans TC", "PingFang TC", sans-serif;
  /* System monospace stack for hash/id/log fragments (Phase M0) — not a
     new font asset, every listed family ships with the OS. */
  --hx-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --hx-text-hero: clamp(3.2rem, 7vw, 7rem);
  --hx-text-h1: clamp(2.2rem, 5vw, 4.4rem);
  --hx-text-h2: clamp(1.5rem, 3vw, 2.2rem);
  --hx-text-h3: 1.18rem;
  --hx-text-body: 1rem;
  --hx-text-lede: clamp(1.02rem, 1.8vw, 1.28rem);
  --hx-text-small: 0.9rem;
  --hx-text-micro: 0.74rem;
  --hx-text-label: 0.72rem;

  /* ---- Spacing ---- */
  --hx-space-1: 4px;
  --hx-space-2: 8px;
  --hx-space-3: 12px;
  --hx-space-4: 18px;
  --hx-space-5: 28px;
  --hx-pad: clamp(16px, 2.6vw, 32px);
  --hx-pad-card: clamp(18px, 2.4vw, 28px);
  --hx-pad-hero: clamp(28px, 6vw, 72px);

  /* ---- Radius ---- */
  --hx-radius-sm: 14px;
  --hx-radius-md: 18px;
  --hx-radius-lg: 26px;
  --hx-radius-xl: 34px;
  --hx-radius-hero: clamp(30px, 4vw, 52px);
  --hx-radius-pill: 999px;

  /* ---- Elevation ---- */
  --hx-shadow-card: 0 22px 64px rgba(16, 40, 42, 0.09);
  --hx-shadow-float: 0 24px 70px rgba(16, 40, 42, 0.12);
  --hx-shadow-dark: 0 24px 80px rgba(0, 0, 0, 0.22);
  --hx-hairline: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  --hx-hairline-dark: inset 0 1px 0 rgba(255, 255, 255, 0.08);

  /* ---- Motion (respect prefers-reduced-motion in base.css) ---- */
  --hx-dur-fast: 160ms;
  --hx-dur-med: 220ms;
  /* Phase M1: sweep/entrance duration. Longer than --hx-dur-med by design
     (motion.css contract: stated reason required) — a sheen must traverse
     the full card width and a staggered entrance must read as a sequence;
     at 220ms both collapse into a flicker. */
  --hx-dur-slow: 640ms;
  --hx-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* ---- Layout & Apple safe-area ---- */
  --hx-page-max: 1180px;
  --hx-page-wide: 1320px;
  --hx-shell-top: max(14px, env(safe-area-inset-top, 0px));
  --hx-shell-h: 70px;
  --hx-page-bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  --hx-blur: blur(24px) saturate(1.12);
}

@media (max-width: 760px) {
  :root {
    --hx-shell-top: max(12px, env(safe-area-inset-top, 0px));
    --hx-shell-h: 124px;
  }
}

/* ---- Visual Composition Refactor V-1 (docs/HANETIC_VISUAL_COMPOSITION_REFACTOR_BRIEF.md §9) ----
   Chassis tokens for the desktop System Rail + the radius-diet/hairline/
   readout vocabulary V-2~V-5 will consume. V-1 only *lands* these — the
   only token here actually applied to a page-content rule this phase is
   the shell radius diet (§2b, next block down); readout/display/density
   sizes are unused until a later phase's own theme file opts in. */
:root {
  /* Rail + canvas dimensions (§2a/§9) */
  --hx-rail-w: 72px;
  --hx-rail-w-short: 56px; /* short landscape, desktop width only — §2c */
  --hx-canvas-max: 1440px;
  --hx-prose-max: 720px;
  --hx-hero-h: clamp(420px, 56svh, 640px);

  /* Rail chassis color — uniform dark #0b1210 family on every page,
     including light-context ones (§2a: "rail 是機殼，不隨頁面換色"). Kept
     as its own token pair rather than folded into --hx-surface-0/1/2
     below: those are the light-context canvas/section/floating-surface
     scale content composition will consume from V-2 on, and nothing in
     V-1 needs a dark counterpart for them yet — inventing one now would
     be a token nobody's consuming. */
  --hx-rail-bg: #0b1210;
  --hx-rail-line: rgba(255, 255, 255, 0.1);
  --hx-rail-ink: rgba(244, 247, 245, 0.86);
  --hx-rail-ink-soft: rgba(244, 247, 245, 0.5);

  /* Surfaces (§9: "畫布 / 分區面 / 浮起面"). Light-context scale; a page's
     own theme still owns any dark-context surface it needs (e.g. Portal/
     Cars already hand-roll their dark glass — --hx-glass-bg* above). */
  --hx-surface-0: var(--hx-bg);
  --hx-surface-1: rgba(255, 255, 255, 0.6);
  --hx-surface-2: rgba(255, 255, 255, 0.88);

  /* Hairline divider rule (§9's "--hx-hairline: 1px solid …"). Named
     --hx-divider* instead of the brief's literal --hx-hairline: that name
     is already the M0-era inset box-shadow "glass top highlight" token
     two lines above (--hx-hairline / --hx-hairline-dark) — reusing it for
     an unrelated 1px solid divider would silently repurpose every
     existing card's highlight the moment any theme picked up the new
     value. --hx-divider is the section/hairline-rule token; the old
     --hx-hairline pair is unchanged and still means "glass highlight." */
  --hx-divider: 1px solid var(--hx-line);
  --hx-divider-dark: 1px solid var(--hx-dark-line-soft);

  /* Radius diet (§9: "0 / 8px / 12px；999px 僅 pill 類"), as three named
     values instead of one shorthand-looking token (custom properties
     can't hold three independently-selected values under one name).
     --hx-radius-shell is the one V-1 actually applies (§2b's explicit
     "28px→16px" number for the mobile/tablet shell chassis) — it isn't
     one of the three §9 content-composition values, it's the shell's own
     number, kept alongside them for discoverability. */
  --hx-radius-flat: 0px; /* 分區 hairline-divided section */
  --hx-radius-plaque: 8px; /* 銘牌格 nameplate/stat block */
  --hx-radius-surface: 12px; /* 浮起面 floating surface (inspector, sheet) */
  --hx-radius-shell: 16px; /* mobile/tablet shell chassis, §2b */

  /* Readout / display typography (§9) */
  --hx-text-readout: clamp(3.5rem, 7vw, 7rem);
  --hx-text-display: clamp(2.6rem, 5vw, 4.6rem);
  /* Fraunces (SIL OFL, mobile-web/assets/fonts/OFL.txt) is Latin+digits
     only (see the @font-face unicode-range below) — its own subset keeps
     every CJK glyph on --hx-font regardless of stacking order, so no
     script-splitting logic is needed anywhere this stack is used. */
  --hx-font-display: "Fraunces", var(--hx-font);

  /* Density (§9) — landed for V-3 (Finance ledger/market rows) and V-2
     (Portal's module list rows); nothing in V-1 renders at these yet. */
  --hx-row-dense: 36px; /* Market table row */
  --hx-row-ledger: 44px; /* Orders ledger row */
  --hx-row-module-list: 52px; /* Portal module list row, §6 */
  --hx-inspector-w: minmax(360px, 0.4fr);

  /* Micro-caps nameplate (label + value pair), §9 bottom. Raw values only
     — no class defined this phase; the pairing is a page-composition
     pattern for V-2~V-5's theme files to build against. */
  --hx-label-size: 0.68rem;
  --hx-label-weight: 900;
  --hx-label-tracking: 0.06em;
  --hx-label-ink-opacity: 0.55;

  /* V-1.1 Expandable System Rail */
  --hx-rail-w-expanded: 232px;
  --hx-rail-w-expanded-short: 208px;
  --hx-rail-expand-dur: 240ms; /* width */
  --hx-rail-label-dur: 180ms; /* label opacity/transform */
  --hx-rail-open-delay: 80ms; /* hover intent, in */
  --hx-rail-close-delay: 260ms; /* hover intent, out */
  --hx-shadow-rail-expanded: 0 18px 60px rgba(0, 0, 0, 0.35);
}

/* Self-hosted display font asset. Weight 600, optical size 72 (Fraunces'
   own recommended display instance), Latin + digits + basic punctuation
   only — unicode-range means the browser never even considers this file
   for a CJK codepoint, independent of font-family fallback order. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/fraunces-display-latin-600.woff2") format("woff2");
  unicode-range: U+21, U+25-26, U+28-29, U+2C-3B, U+3F, U+41-5A, U+61-7A, U+B0, U+2013-2014;
}
/* Header sticks at the document edge; safe-area space is inside its padding. */
:root { --hx-child-top: 0px; }
/* Accepted child header sizes, including status-area space. */
:root { --hx-child-bar-pad: 12px; --hx-child-brand-left: 80px; --hx-child-height-default: calc(76px + env(safe-area-inset-top, 0px)); --hx-child-height: var(--hx-child-height-default); --hx-child-drawer-duration: 640ms; }
@media (max-width: 760px) { :root { --hx-child-bar-pad: 8px; --hx-child-brand-left: 68px; --hx-child-height-default: calc(68px + env(safe-area-inset-top, 0px)); } }
@media (max-height: 560px) { :root { --hx-child-bar-pad: 4px; --hx-child-height-default: calc(52px + env(safe-area-inset-top, 0px)); } }
