@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@0,400;0,500;0,600;1,400&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500;600&family=Noto+Sans+TC:wght@400;500;600;700&display=swap');

/*
 * Shared design-system stylesheet for the mallowsai site.
 *
 * Single source of truth for design tokens (color, spacing, type scale),
 * the top navigation / mega-menu, and other cross-page patterns (buttons,
 * badges, hero-card layout, base typography). Served as a static file by
 * src/server.ts at /styles.css.
 *
 * Page-specific styles (e.g. roadmap.html's canvas diagram/pathway timeline,
 * dashboard.html's insight cards, links.html's demo form/table) stay in a
 * small <style> block in that page rather than living here.
 */

:root {
  color-scheme: light;

  /* =========================================================
     Mallows.ai — Sky / Modular editorial design tokens.
     Canonical palette/type imported from the homepage design
     system; the legacy variable NAMES below are preserved and
     RE-POINTED to these new values so every existing page picks
     up the new look without any markup change.
     ========================================================= */

  /* ---------- PRIMARY · Sky ---------- */
  --sky-50:#F2F8FF; --sky-100:#E3F0FF; --sky-200:#C4DFFF; --sky-300:#93C5FE;
  --sky-400:#57A4FA; --sky-500:#2286F0; --sky-600:#0A66D0; --sky-700:#0A4E9E;

  /* ---------- PRIMARY · Violet (brand identity) ---------------------------
     Per system-branding.html's brand brief: purple is now Mallows.ai's main
     identity color ("想像力、洞察與有節制的個性"); Sky blue steps down to a
     functional "data & order" role (kept below, unchanged) rather than
     disappearing. 600/700 are Bennet's own hand-picked values already live
     on the homepage hero (.home .hero-kicker / .home .hero h1 em in
     index.html) -- this scale is built AROUND those two anchors, not a
     separate guess, so the rest of the site lands on the exact same purple
     rather than a merely-similar one.
     600 (#7C4DAD) on white: 5.96:1 contrast -- passes WCAG AA (4.5:1) for
     solid-fill button text. 700 (#6D43A6) on white: 6.99:1. Both verified
     directly, the same way the original --accent tuning documented its own
     contrast math below. */
  --violet-50:#F7F3FF; --violet-100:#ECE3FA; --violet-200:#D9C8F5; --violet-300:#BC9EEA;
  --violet-400:#9E76DC; --violet-500:#8B5FC9; --violet-600:#7C4DAD; --violet-700:#6D43A6;

  /* ---------- INK · navy hierarchy ---------- */
  --ink-900:#0C1826; --ink-800:#16283D; --ink-700:#233A55; --ink-600:#38506D;
  --ink-500:#5A7C97;

  /* ---------- NEUTRALS · cloud & fog ---------- */
  --canvas:#FBFCFE;
  --surface:#FFFFFF;
  --surface-sunk:#F4F7FB;
  --fog:#EDF2F8;
  --stroke:#E4EBF3;
  --stroke-strong:#CEDAE8;

  --text-strong:#0C1826;
  --text-body:#38506D;
  --text-subtle:#6E829B;
  --on-dark:#FFFFFF;

  /* ---------- WARMTH · the Mallows lineage ---------- */
  --sand-50:#FDF7F1;
  --sand-100:#F7EDE2;
  --amber-400:#F5B33F;
  --amber-600:#B9791A;

  /* ---------- SUPPLEMENTARY ACCENTS (soft claymorphism palette) ----------
     Four NEW named accent hues added to break up the sky-blue-heavy homepage.
     Sky stays the primary brand colour; these are used narrowly as per-item
     accents (one per productivity tile, rotating with teal). Each has a solid
     value (for glyphs / borders / shadows) plus a pale tint (for backgrounds).
     Hues chosen for maximum mutual distinctness and to sit next to a pastel,
     matte "clay" aesthetic: coral (warm red-orange), periwinkle-violet,
     fresh mint-green, and a rose/pink (chosen over a sunny gold, which would
     read too close to the existing --amber used on the Work Recap pillar). */
  --sup-coral:#F2765C;  --sup-coral-tint:#FCE7E1;
  --sup-violet:#7C6CF0;  --sup-violet-tint:#E9E6FC;
  --sup-mint:#3FA85F;   --sup-mint-tint:#DDF2E4;
  --sup-rose:#E86A9A;   --sup-rose-tint:#FBE5EF;

  /* ---------- PILLAR SUB-FLAVOURS ---------- */
  --recap:#2286F0; --recap-alt:#F5B33F; --recap-tint:#E3F0FF;
  --tools:#0E9E8E; --tools-tint:#DCF5F1; --tools-ink:#087A6D;
  --cosec:#233A55; --cosec-tint:#EBF0F7; --cosec-accent:#0A66D0;

  /* ---------- SEMANTIC · status only ---------- */
  --ok:#10A37F;    --ok-tint:#DDF5EE;
  --warn:#DE9414;  --warn-tint:#FCF0DA;
  --risk:#D14343;  --risk-tint:#FBE7E7;

  --brand:var(--violet-600);
  --brand-strong:var(--violet-700);
  --brand-press:var(--violet-700);
  --brand-tint:var(--violet-50);
  --focus-ring:0 0 0 4px rgba(124,77,173,.28);

  /* Sky's functional role now that violet owns primary/brand: "data & order"
     surfaces -- tables, registers, forms, the compliance calendar -- keep
     reading as sky blue, deliberately distinct from violet's brand/action
     role per the same brief. Plain aliases, not new colors, so existing
     --sky-* usage (e.g. auth-page focus rings) stays correct with no change. */
  --data-accent:var(--sky-500);
  --data-accent-dark:var(--sky-600);

  /* ---------- editorial type scale (new) ---------- */
  --font-mono:'IBM Plex Mono','Noto Sans TC',ui-monospace,monospace;
  --text-hero:clamp(2.6rem,1.5rem + 3.9vw,4.25rem);
  --text-h1:clamp(2.1rem,1.5rem + 2.2vw,3rem);
  --text-h2:clamp(1.6rem,1.3rem + 1.2vw,2.1rem);
  --text-h3:1.3125rem;
  --text-lg:1.0625rem;
  --text-base:1rem;
  --text-sm:.875rem;
  --text-label:.75rem;
  --lh-tight:1.06; --lh-snug:1.25; --lh-normal:1.62;
  --tracking-tight:-.022em; --tracking-label:.12em;

  /* ---------- 4px space scale (new) ---------- */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;
  --s7:48px; --s8:64px; --s9:96px; --s10:128px;

  /* ---------- modular radius (new) ---------- */
  --r-xs:6px; --r-sm:10px; --r-md:14px; --r-lg:20px; --r-xl:28px; --r-pill:999px;

  /* ---------- cool, low elevation (new) ---------- */
  --shadow-xs:0 1px 2px rgba(12,24,38,.05);
  --shadow-sm:0 2px 8px rgba(12,24,38,.06);
  --shadow-md:0 12px 28px rgba(12,24,38,.08);
  --shadow-lg:0 28px 64px rgba(12,24,38,.12);
  --shadow-brand:0 12px 28px rgba(124,77,173,.26);

  /* ---------- layout (new) ---------- */
  --container:1440px;
  --container-tight:940px;
  --gutter:clamp(20px,5vw,56px);

  /* ---- legacy color tokens, RE-POINTED again: sky -> violet ----
     This pair was previously tuned to a brightened sky blue (#1473DD); see
     git history for that reasoning. Per system-branding.html's brand brief
     ("品牌主色改為 Purple"), --accent/--accent-dark now point at the violet
     scale above instead, carrying the same site-wide reach (.eyebrow, .cta,
     link hovers, and everywhere else that already read --accent) without
     any markup changes. Contrast is verified against the violet-600/700
     scale comment above, not re-derived here. */
  --bg: var(--canvas);
  --card: var(--surface);
  --text: var(--text-strong);
  --muted: var(--text-subtle);
  --accent: var(--violet-600);
  --accent-dark: var(--violet-700);

  /* ---- secondary accent: Mango (warm orange/amber), the second brand-family
     color deliberately promoted to real UI use (not just a reserved tier
     tint) so the site has more than one color note. Paired against Sky blue
     as a classic cool/warm complementary pair. Brightened from the original
     muted --amber-600 (#b9791a, chosen only for its 5.02:1 contrast margin)
     to a more saturated, energetic orange: #c2410c on white text = 5.9:1
     contrast (still WCAG AA), while reading noticeably warmer/punchier than
     the old brown-amber. --accent-secondary-dark is a hover-state shade one
     step darker. */
  --accent-secondary: #c2410c;
  --accent-secondary-dark: #9a3412;
  --border: var(--stroke);
  --container-width: 1440px;

  /* ---- brand accent tag colors (Mallow brand family: Sky / Mango / Mint) ----
     Pale tints (background) kept deliberately soft so badge text stays
     legible at small sizes; the TEXT colors were brightened from muted
     slate/olive tones to the same punchier, more saturated hues used
     elsewhere (--accent, --accent-secondary, --sup-mint) so the badges read
     as vivid accents rather than washed-out pastels next to them.

     NOTE: --accent is now Sky blue (the same brand family as --tier-sky below).
     --tier-sky is kept as-is (a pale pastel background) so it still reads as
     visually distinct from CTA/button chrome for now. But when the
     Sky/Mango/Mint 3-tier tagging system is actually built, having the
     primary accent and one of the three tier colors share the same hue
     family will likely read as confusing (e.g. a "Sky" tier badge sitting
     next to a primary CTA in the same blue). At that point, prefer swapping
     this tier's hue for something clearly distinct from --accent (e.g. an
     indigo/violet) rather than keeping Sky as both the primary accent and a
     tier color. */
  --tier-sky: #eaf3fb;
  --tier-sky-text: var(--sky-600);
  --tier-mango: #fdf1de;
  --tier-mango-text: var(--accent-secondary);
  --tier-mint: #e7f5ee;
  --tier-mint-text: var(--sup-mint);

  /* ---- typography: Fredoka for display/headlines, Nunito for body/UI,
     both paired with Noto Sans TC for Traditional Chinese copy ---- */
  --font-display: 'Newsreader', 'Noto Serif TC', Georgia, serif;
  --font-body: 'Plus Jakarta Sans', 'Noto Sans TC', 'PingFang TC', system-ui, sans-serif;

  /* ---- spacing scale (rem-based; 1 = 16px) ---- */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem; /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.5rem; /* 24px */
  --space-6: 2rem; /* 32px */
  --space-7: 3rem; /* 48px */

  /* ---- responsive padding patterns, applied uniformly instead of mixing
     fixed-px and clamp() paddings arbitrarily ---- */
  --pad-container: clamp(1rem, 4vw, 2rem); /* nav/main/.page horizontal gutter, 16px -> 32px */
  --pad-card: clamp(1.25rem, 2.5vw, 1.5rem) var(--space-5); /* card/notice/panel padding, ~20px -> 24px vertical */
  --pad-section: clamp(2rem, 6vw, 3rem) clamp(1.5rem, 5vw, 2.5rem); /* hero-card padding, 32px -> 48px vertical, 24px -> 40px horizontal */

  /* ---- type scale: a small number of deliberate sizes, used identically
     everywhere instead of ad-hoc per-file clamp() values ---- */
  --font-size-xs: 0.75rem; /* 12px */
  --font-size-sm: 0.875rem; /* 14px */
  --font-size-base: 1rem; /* 16px */
  --font-size-md: 1.125rem; /* 18px */
  --font-size-lg: 1.25rem; /* 20px */
  --font-size-xl: clamp(1.5rem, 3vw, 1.75rem); /* section h2 */
  --font-size-2xl: clamp(1.8rem, 4vw, 2.6rem); /* dashboard h1 */
  --font-size-3xl: clamp(2rem, 5.5vw, 3rem); /* secondary hero h1 (tools/company-secretary/pricing/roadmap) */
  --font-size-4xl: clamp(2.2rem, 6.5vw, 3.6rem); /* primary hero h1 (index) */
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body);
  color: var(--text);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
}

/* Pages with a decorative hero (index/tools/company-secretary/pricing/roadmap)
   opt in to a soft sky glow via this class on <body>. */
body.hero-bg {
  background:
    radial-gradient(circle at top left, rgba(34, 134, 240, 0.14), transparent 34%),
    radial-gradient(circle at bottom right, rgba(87, 164, 250, 0.10), transparent 30%),
    var(--canvas);
}

/* ---- shared top navigation (index.html / dashboard.html / tools.html / company-secretary.html / pricing.html / roadmap.html) ---- */
nav.site-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  width: 100%;
  background: rgba(251, 252, 254, 0.86);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

nav.site-nav .nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  max-width: var(--container-width);
  margin: 0 auto;
  padding: var(--space-4) var(--pad-container);
  position: relative;
}

nav.site-nav .brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: var(--font-size-lg);
  letter-spacing: -0.02em;
  color: var(--text-strong);
  text-decoration: none;
}

/* Brand logo mark: the small gradient "glyph" tile that sits before the
   wordmark (retrieved from the imported design's .logo .glyph). */
nav.site-nav .brand .glyph {
  width: 24px;
  height: 24px;
  flex: none;
  border-radius: 7px;
  background: linear-gradient(150deg, var(--sky-400), var(--sky-600));
  position: relative;
  box-shadow: var(--shadow-xs);
}
nav.site-nav .brand .glyph::after {
  content: "";
  position: absolute;
  inset: 6px 6px auto 6px;
  height: 6px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.85);
}

nav.site-nav ul.nav-list {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Mobile hamburger toggle: a checkbox-hack pair (no JS) sitting between the
   brand and .nav-list in the markup, so `.nav-toggle-input:checked ~
   .nav-list` can show/hide the list purely via CSS. Hidden on desktop; the
   @media (max-width: 720px) block below turns .nav-burger into the visible
   toggle button and collapses .nav-list behind it. */
.nav-toggle-input {
  display: none;
}

.nav-burger {
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-strong, var(--muted));
  padding: 6px;
}

nav.site-nav .nav-item {
  /* Deliberately static, not relative: the mega-panel below positions itself
     against nav.site-nav (the full nav bar), not against this individual
     nav-item, so the dropdown can span the whole nav width ("full width
     submenu") instead of being a narrow panel hanging off one label. */
  position: static;
}

nav.site-nav a.nav-link,
nav.site-nav button.nav-link {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  text-decoration: none;
  font-size: var(--font-size-sm);
  font-family: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

nav.site-nav a.nav-link:hover,
nav.site-nav button.nav-link:hover {
  color: var(--accent-dark);
}

nav.site-nav a.nav-link[aria-current="page"] {
  color: var(--accent-dark);
  font-weight: 700;
}

/* The dropdown caret (▾) was removed: at nav scale it rendered as a stray
   dot/period next to the free/soon-推出 badges rather than a legible arrow,
   reported as visual clutter. The mega-panel open/close affordance is
   still fully conveyed by aria-haspopup/aria-expanded plus the hover/click
   interaction itself. */

/* Nav tags render as small raised superscripts sitting just after the label
   (免費 after 打工年報; 即將推出 after 公司秘書/人力資源/收費), rather than
   full inline pills. `sup` gives the raised baseline; we keep a tiny pill
   background for legibility. */
nav.site-nav .soon-badge {
  margin-left: 3px;
  padding: 1px 5px;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  line-height: 1;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  background: var(--sky-100);
  color: var(--sky-700);
  vertical-align: super;
}

nav.site-nav .free-badge {
  margin-left: 3px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 0.58rem;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 0.03em;
  /* Mango (secondary accent), not Sky blue or Violet: keeps this badge
     distinct from both --accent (now Violet, used for every CTA/nav
     highlight) and .soon-badge's Sky pill (the "data & order" role). Mango
     makes the one badge that actually matters (免費) pop against both. */
  background: var(--accent-secondary);
  color: #fff;
  vertical-align: super;
}

/* ---- language switch in the nav (繁 / EN sliding toggle) ---- */
nav.site-nav .nav-lang {
  display: inline-flex;
}
.lang-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 3px;
  border: 1px solid var(--stroke-strong);
  border-radius: 999px;
  background: var(--surface-sunk);
  cursor: pointer;
  font-family: var(--font-body);
  line-height: 1;
}
.lang-switch .lang-switch-opt {
  position: relative;
  z-index: 1;
  min-width: 2.2em;
  text-align: center;
  padding: 4px 8px;
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--text-subtle);
  transition: color 0.16s ease;
}
.lang-switch .lang-switch-knob {
  position: absolute;
  z-index: 0;
  top: 3px;
  left: 3px;
  width: calc(50% - 3px);
  height: calc(100% - 6px);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  transition: transform 0.18s ease;
}
.lang-switch[aria-checked="true"] .lang-switch-knob {
  transform: translateX(100%);
}
.lang-switch[aria-checked="false"] .lang-opt-tc,
.lang-switch[aria-checked="true"] .lang-opt-en {
  color: var(--sky-700);
}
.lang-switch:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* Full-width mega-panel: positioned against nav.site-nav (position: relative,
   full page width) rather than the individual .nav-item, so it spans the
   same width as the nav bar's constrained inner container instead of being a
   narrow dropdown centered under one label. */
nav.site-nav .mega-panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: var(--container-width);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-2);
  padding: var(--space-4) var(--pad-container);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  border: 1px solid var(--border);
  border-top: none;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  z-index: 20;
}

/* Bridges the hover "dead zone" between the trigger and the panel: .mega-panel
   is positioned against .nav-inner (its nearest positioned ancestor), whose
   top: 100% lands at .nav-inner's own bottom edge -- but .nav-inner has
   padding-bottom: var(--space-4), so the visible .nav-item (the <li>) actually
   ends var(--space-4) above that. That padding band belongs to .nav-inner,
   not to .nav-item, so it isn't covered by any hoverable box and moving the
   mouse straight down from the trigger into the panel used to cross it and
   drop out of :hover, closing the menu before the cursor arrived. This
   pseudo-element is a DOM-generated part of .mega-panel (itself a descendant
   of .nav-item), so it extends .nav-item's hoverable box up over that exact
   gap with no interruption. It only exists while .mega-panel is displayed
   (display: none on the panel suppresses box generation for its pseudo-
   elements too), so it can't be hovered before the menu has actually opened. */
nav.site-nav .mega-panel::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  /* Cover the FULL gap between the trigger and the panel. The nav row is
     align-items: center, so a short mega-trigger sits centered with slack
     below it (relative to the taller 登入 pill / language switch), on top of
     .nav-inner's var(--space-4) padding-bottom. var(--space-4) alone left a
     few px uncovered, so the menu closed while the cursor crossed it. Using
     var(--space-6) spans the padding + the centering slack with margin to
     spare, so the hover never drops. */
  top: calc(-1 * var(--space-6));
  height: var(--space-6);
}

nav.site-nav .nav-item.has-mega:hover .mega-panel,
nav.site-nav .nav-item.has-mega:focus-within .mega-panel,
nav.site-nav .nav-item.has-mega.open .mega-panel {
  display: grid;
}

nav.site-nav .mega-link {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: 10px;
  color: var(--text);
  text-decoration: none;
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

nav.site-nav .mega-link:hover,
nav.site-nav .mega-link:focus-visible {
  background: var(--sky-50);
  color: var(--accent-dark);
}

nav.site-nav .mega-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  color: var(--sky-600);
}

nav.site-nav .mega-link-text {
  min-width: 0;
}

nav.site-nav .mega-desc {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--muted);
  overflow-wrap: anywhere;
}

nav.site-nav a.nav-link.nav-cta {
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  box-shadow: var(--shadow-brand);
}

nav.site-nav a.nav-link.nav-cta:hover {
  background: var(--accent-dark);
  color: #fff;
}

/* ---- profile icon + dropdown (logged-in nav-cta replacement) ----
   Shared markup lives identically in every nav-bearing page's canonical nav;
   /api/me-driven JS (also duplicated identically, see the "hide 系統" script
   block) toggles which of #nav-login-item / #nav-profile-item is visible. */
nav.site-nav .nav-profile {
  position: relative;
}

nav.site-nav .nav-profile-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--sky-100);
  color: var(--accent-dark);
  cursor: pointer;
  overflow: hidden;
}

nav.site-nav .nav-profile-trigger:hover,
nav.site-nav .nav-profile-trigger:focus-visible {
  background: var(--sky-200);
}

nav.site-nav .nav-profile-avatar-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

nav.site-nav .nav-profile-initial {
  font-size: var(--font-size-sm);
  font-weight: 700;
  line-height: 1;
}

nav.site-nav .nav-profile-panel {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: var(--space-2);
  min-width: 220px;
  padding: var(--space-3);
  border-radius: var(--r-lg);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  z-index: 20;
}

nav.site-nav .nav-profile.open .nav-profile-panel {
  display: block;
}

nav.site-nav .nav-profile-email {
  padding: 0 var(--space-2) var(--space-2);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--muted);
  overflow-wrap: anywhere;
}

nav.site-nav .nav-profile-link {
  display: block;
  width: 100%;
  padding: var(--space-2);
  border: none;
  background: none;
  border-radius: 8px;
  color: var(--text, var(--muted));
  font-size: var(--font-size-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  font-family: var(--font-body);
}

nav.site-nav .nav-profile-link:hover,
nav.site-nav .nav-profile-link:focus-visible {
  background: var(--sky-50);
  color: var(--accent-dark);
}

@media (max-width: 720px) {
  nav.site-nav .nav-inner {
    justify-content: space-between;
  }

  nav.site-nav .nav-burger {
    display: inline-flex;
  }

  nav.site-nav ul.nav-list {
    display: none;
    width: 100%;
  }

  nav.site-nav .nav-toggle-input:checked ~ ul.nav-list {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    margin-top: var(--space-3);
  }

  nav.site-nav .nav-item.has-mega {
    width: 100%;
    min-width: 0;
  }

  nav.site-nav .mega-panel {
    position: static;
    transform: none;
    width: 100%;
    max-width: none;
    min-width: 0;
    grid-template-columns: 1fr;
    margin-top: var(--space-2);
    border-radius: 16px;
    border-top: 1px solid var(--border);
    box-shadow: none;
  }

  /* Mobile stacks the panel in normal flow (position: static) via the
     click-toggle .open class, not hover, so there's no dead zone to bridge
     here -- suppress the desktop hover-gap bridge so it doesn't render as a
     stray absolutely-positioned strip inside the stacked layout. */
  nav.site-nav .mega-panel::before {
    content: none;
  }
}
/* ---- end shared top navigation ---- */

/* ---- shared left sidebar nav (added identically to every authenticated
   page: dashboard, tools and the tool-* pages, company-secretary, account,
   change-password,
   pricing/roadmap/comsec-use-cases/system-*.html; markup+script duplicated
   byte-for-byte the same way nav.site-nav above is). Hidden by default so a
   logged-out visitor never sees it flash; the page's own inline script
   reveals it (via body.has-sidebar) only once /api/me confirms loggedIn.

   Desktop (>960px): a persistent ~240px left rail sitting beside
   nav.site-nav via a body-level CSS grid (nav spans both columns on row 1;
   sidebar + main/.page split row 2).

   Mobile (<=960px): the rail becomes an off-canvas drawer driven by the
   .sidebar-toggle-input checkbox-hack -- the same no-JS show/hide technique
   as .nav-toggle-input above, but its own checkbox/id so it can't be
   toggled by (or fight with) the top nav's 720px hamburger. Opened via the
   floating .sidebar-fab button, closed via .sidebar-close or tapping the
   .sidebar-backdrop. 960px is deliberately its own breakpoint, wider than
   nav.site-nav's 720px collapse: a 240px rail plus readable content needs
   more headroom than the nav bar alone before it should give way. ---- */
.sidebar-toggle-input {
  display: none;
}

.app-sidebar {
  display: none;
}

.sidebar-backdrop {
  display: none;
}

.sidebar-fab {
  display: none;
}

body.has-sidebar {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr;
}

body.has-sidebar > nav.site-nav {
  grid-column: 1 / -1;
  grid-row: 1;
}

/* With a left rail present this is an app shell, not a centred marketing
   header: .nav-inner's max-width + `margin: 0 auto` pushed the brand well to
   the right of the rail beneath it, so the logo visibly failed to line up
   with the sidebar's own links. Left-align it instead and match the rail's
   text inset -- the sidebar's horizontal padding (--space-3) plus each
   .sidebar-link's own padding (--space-3) -- so the brand sits directly
   above the first menu item. */
body.has-sidebar > nav.site-nav .nav-inner {
  max-width: none;
  margin: 0;
  padding-left: calc(var(--space-3) * 2);
  padding-right: var(--pad-container);
}

body.has-sidebar > .app-sidebar {
  display: flex;
  flex-direction: column;
  grid-column: 1;
  grid-row: 2;
  width: 240px;
  padding: var(--space-5) var(--space-3);
  border-right: 1px solid var(--border);
  background: var(--sky-50);
}

body.has-sidebar > main,
body.has-sidebar > .page {
  grid-column: 2;
  grid-row: 2;
  min-width: 0;
}

/* .hero-card's --pad-section inset (40px horizontal at this width) is sized
   for a full-bleed marketing hero. On an app page it is stacked directly
   above .tool-card panels, whose --pad-card inset is 24px, so the two
   headings started 16px apart down the same column. Match the panel inset
   here so everything in the content column shares one left edge; the taller
   vertical padding stays, since that spacing still reads as a page header. */
body.has-sidebar .hero-card {
  padding-left: var(--space-5);
  padding-right: var(--space-5);
  /* .tool-card carries margin-bottom: var(--space-5) between stacked panels,
     but .hero-card carries none, so the page header sat noticeably tighter
     against the first panel than the panels sit against each other. Match the
     same rhythm. */
  margin-bottom: var(--space-5);
}

/* The 44rem measure below is a readability limit for long marketing prose.
   In the app shell the hero is a short one-or-two-sentence page header
   sitting in an already-narrowed content column, where that cap only forces
   an early wrap and leaves the line visibly short of the card's right edge.
   Let it use the full width here; the marketing pages keep the measure. */
body.has-sidebar .hero-card .subheadline {
  max-width: none;
}

.app-sidebar .sidebar-close {
  display: none;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* The sidebar is grouped by what the entries are FOR (company secretary work,
   free tools, settings, staff-only operation/system) rather than one flat run
   of ten links -- the flat list gave no clue which entries a given person was
   ever going to use. */
.sidebar-group + .sidebar-group {
  margin-top: var(--space-4);
}

.sidebar-group-title {
  margin: 0 0 var(--space-1);
  padding: 0 var(--space-3);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0.72;
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: 10px;
  color: var(--muted);
  text-decoration: none;
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.sidebar-link:hover,
.sidebar-link:focus-visible {
  background: var(--sky-100);
  color: var(--accent-dark);
}

.sidebar-link[aria-current="page"] {
  background: var(--sky-100);
  color: var(--accent-dark);
}

.sidebar-icon {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--sky-600);
}

@media (max-width: 960px) {
  body.has-sidebar {
    grid-template-columns: 1fr;
  }

  body.has-sidebar > nav.site-nav {
    grid-column: 1;
  }

  body.has-sidebar > .app-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    box-shadow: var(--shadow-lg);
  }

  body.has-sidebar .sidebar-toggle-input:checked ~ .app-sidebar {
    transform: translateX(0);
  }

  body.has-sidebar .sidebar-toggle-input:checked ~ .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(12, 24, 38, 0.35);
    z-index: 55;
  }

  body.has-sidebar .sidebar-fab {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    left: var(--space-4);
    bottom: var(--space-4);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    box-shadow: var(--shadow-brand);
    z-index: 56;
    cursor: pointer;
  }

  body.has-sidebar .sidebar-toggle-input:checked ~ .sidebar-fab {
    display: none;
  }

  .app-sidebar .sidebar-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: flex-end;
    width: 28px;
    height: 28px;
    margin-bottom: var(--space-2);
    border-radius: 50%;
    color: var(--muted);
    cursor: pointer;
  }

  body.has-sidebar > main,
  body.has-sidebar > .page {
    grid-column: 1;
  }
}
/* ---- end shared left sidebar nav ---- */

/* ---- shared drag & drop / paste / click file input component (app.js) ---- */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-6) var(--space-4);
  border: 2px dashed var(--border);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.5);
  color: var(--muted);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.dropzone:hover,
.dropzone:focus-visible {
  border-color: var(--accent);
  outline: none;
}

.dropzone.dropzone-active {
  border-color: var(--accent);
  background: var(--sky-50);
  color: var(--accent-dark);
}

.dropzone .dropzone-title {
  font-weight: 700;
  color: var(--text);
}
/* ---- end shared drag & drop / paste / click file input component ---- */

/* ---- shared page container ---- */
main,
.page {
  width: 100%;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: var(--space-3) var(--pad-container) var(--space-7);
}
/* ---- end shared page container ---- */

/* ---- shared hero-card pattern (index/tools/company-secretary/pricing/roadmap) ---- */
.hero-card {
  padding: var(--pad-section);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  background: var(--card);
  box-shadow: 0 18px 40px rgba(83, 52, 120, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--font-size-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-dark);
}

.eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.6), 0 2px 4px rgba(77, 42, 119, 0.25);
}

.hero-card h1 {
  margin: 0;
  font-size: var(--font-size-3xl);
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.hero-card .subheadline {
  margin: var(--space-5) 0 0;
  max-width: 44rem;
  font-size: var(--font-size-md);
  line-height: 1.7;
  color: var(--muted);
}

.hero-card ul.bullets {
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.hero-card ul.bullets li {
  margin: var(--space-2) 0;
  font-size: var(--font-size-md);
  color: var(--text);
}

.cta {
  display: inline-block;
  margin-top: var(--space-6);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--r-sm);
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  font-size: var(--font-size-md);
  text-decoration: none;
  box-shadow: var(--shadow-brand);
}

.cta:hover {
  background: var(--accent-dark);
}

@media (max-width: 640px) {
  .hero-card {
    border-radius: 22px;
  }
}
/* ---- end shared hero-card pattern ---- */

/* ---- shared pill-toggle buttons (index.html region toggle, dashboard.html range switcher) ---- */
.pill-toggle {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
}

.pill-toggle button {
  font-family: inherit;
  font-size: var(--font-size-sm);
  padding: var(--space-2) var(--space-4);
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
  cursor: pointer;
}

.pill-toggle button[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
/* ---- end shared pill-toggle buttons ---- */

/* ---- shared card pattern (dashboard insight cards / notices reuse this padding rhythm) ---- */
.pad-card {
  padding: var(--pad-card);
  border-radius: 20px;
  border: 1px solid var(--border);
}
/* ---- end shared card pattern ---- */

/* ---- shared image treatment ---- */
.avatar-img {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}
/* ---- end shared image treatment ---- */

/* =========================================================================
   HOMEPAGE (Sky / Modular editorial) component classes.
   Everything below is scoped under `.home` (the class on the homepage
   <body>) so these homepage-only components never alter interior pages.
   Class names that also exist in the shared styles above (notably
   `.eyebrow`, `footer`, `.logo`) are intentionally scoped here so the
   interior-page meaning of those names is untouched.
   ========================================================================= */
.home{background:var(--canvas);color:var(--text-body);font-family:var(--font-body);font-size:var(--text-base);line-height:var(--lh-normal)}
.home a{color:var(--sky-600);text-decoration:none}
.home a:hover{color:var(--sky-700)}
.home p{margin:0}
.home h1,.home h2,.home h3,.home h4{margin:0;color:var(--text-strong);line-height:var(--lh-snug);font-weight:600}
.home .wrap{max-width:var(--container);margin:0 auto;padding:0 var(--gutter)}
.home .tight{max-width:var(--container-tight);margin:0 auto;padding:0 var(--gutter)}
.home .serif{font-family:var(--font-display);font-weight:400;letter-spacing:var(--tracking-tight)}
.home .mono{font-family:var(--font-mono)}
.home .eyebrow{display:inline-block;margin:0;padding:0;border-radius:0;background:none;font-family:var(--font-body);font-size:var(--text-label);font-weight:700;letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--sky-600)}
.home .lede{font-size:var(--text-lg);color:var(--text-body);max-width:60ch}
.home .sec{padding:var(--s9) 0}
.home .sec-head{max-width:64ch;margin-bottom:var(--s7)}
.home .sec-head h2{font-size:var(--text-h1)}
.home .sec-head p{margin-top:var(--s4)}

/* buttons
   Global (unscoped): .btn/.btn-primary/.btn-ghost/.btn-quiet are a generic
   reusable component, and every design token they reference (--s2, --text-sm,
   --sky-600, etc.) is a plain :root value with no page-specific meaning. This
   used to be scoped to .home/.auth-page only, which meant any other page
   using these classes (dashboard.html's Focus Time/timezone-overlap buttons,
   system-tickets.html) silently fell back to unstyled, tiny browser-default
   buttons -- the same class of bug the .auth-page scope was added to fix
   once already. Scoping this to specific body classes each time a new page
   adopts .btn is a recurring trap; making it global closes it for good. */
.btn{display:inline-flex;align-items:center;gap:var(--s2);font-family:var(--font-body);font-weight:600;font-size:var(--text-sm);padding:13px 22px;border-radius:var(--r-sm);border:1px solid transparent;cursor:pointer;transition:.16s;text-decoration:none}
.btn-primary{background:var(--accent);color:#fff;box-shadow:var(--shadow-brand)}
.btn-primary:hover{background:var(--accent-dark);color:#fff;transform:translateY(-1px)}
.btn-ghost{background:var(--surface);color:var(--text-strong);border-color:var(--stroke-strong);box-shadow:var(--shadow-xs)}
.btn-ghost:hover{border-color:var(--sky-300);color:var(--text-strong)}
.btn-quiet{background:transparent;color:var(--text-body);padding:13px 6px}
.btn-quiet:hover{color:var(--sky-600)}

/* chips */
.home .chip{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-sm);font-weight:600;padding:5px 11px;border-radius:var(--r-pill);border:1px solid var(--stroke)}
.home .chip-ok{background:var(--ok-tint);color:#0A7B60;border-color:transparent}
.home .chip-warn{background:var(--warn-tint);color:var(--amber-600);border-color:transparent}
.home .chip-risk{background:var(--risk-tint);color:#A93030;border-color:transparent}
.home .chip-neutral{background:var(--surface-sunk);color:var(--text-subtle)}
.home .dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}

/* footer/logo wordmark used in homepage footer */
.home .logo{display:flex;align-items:center;gap:9px;font-weight:800;font-size:1.0625rem;color:var(--text-strong);letter-spacing:-.02em}
.home .logo .glyph{width:26px;height:26px;border-radius:8px;background:linear-gradient(150deg,var(--sky-400),var(--sky-600));position:relative;box-shadow:var(--shadow-xs)}
.home .logo .glyph::after{content:"";position:absolute;inset:6px 6px auto 6px;height:7px;border-radius:99px;background:rgba(255,255,255,.85)}

/* ---------- HERO ---------- */
.home .hero{position:relative;overflow:hidden;padding:var(--s10) 0 var(--s9);background:linear-gradient(155deg,#FCFAFF 0%,#F7F3FF 48%,#F6FBFA 100%)}
.home .hero::before{content:"";position:absolute;inset:-30% 40% 40% -10%;background:radial-gradient(closest-side,rgba(166,119,226,.18),transparent);pointer-events:none}
.home .hero-grid{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:var(--s8);align-items:center}
.home .hero-kicker{display:inline-flex;align-items:center;gap:var(--s2);color:#6D43A6;font-family:var(--font-mono);font-size:var(--text-label);font-weight:700;letter-spacing:var(--tracking-label);text-transform:uppercase}
.home .hero-kicker::before{content:"";width:10px;height:10px;border-radius:50%;background:#7C4DAD;box-shadow:inset 0 1px 1px rgba(255,255,255,.6),0 2px 4px rgba(77,42,119,.25)}
.home .hero h1{font-family:var(--font-display);font-weight:400;font-size:var(--text-hero);letter-spacing:var(--tracking-tight);line-height:var(--lh-tight)}
.home .hero h1 em{font-style:italic;color:#7043AB}
.home .hero .lede{margin-top:var(--s5)}
.home .hero-cta{display:flex;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s6)}
.home .hero-note{margin-top:var(--s4);font-size:var(--text-sm);color:var(--text-subtle)}

/* Clay illustration is the homepage's visual anchor. The small floating
   notes reuse the same raised, matte treatment later used by status chips
   and process cards, so this does not become one isolated marketing image. */
.home .hero-visual{position:relative;min-height:430px;border-radius:var(--r-xl);overflow:hidden;background:#F8F4FE;box-shadow:0 22px 56px rgba(83,52,120,.13),inset 0 1px 0 rgba(255,255,255,.85)}
.home .hero-visual img{display:block;width:100%;height:100%;min-height:430px;object-fit:cover;object-position:center right}
.home .hero-clay-note{position:absolute;display:flex;align-items:center;gap:8px;padding:10px 14px;border-radius:15px;background:rgba(255,255,255,.92);border:1px solid rgba(255,255,255,.9);box-shadow:0 9px 18px rgba(65,38,93,.16),inset 0 1px 0 #fff;color:#443C50;font-size:var(--text-sm);font-weight:650;backdrop-filter:blur(8px)}
.home .hero-clay-note-top{top:28px;left:24px}.home .hero-clay-note-bottom{right:24px;bottom:24px}
.home .hero-clay-dot{width:10px;height:10px;border-radius:50%;background:#70A98B;box-shadow:inset 0 1px 1px rgba(255,255,255,.75),0 2px 4px rgba(51,111,75,.28)}
.home .hero-clay-check{display:grid;place-items:center;width:18px;height:18px;border-radius:7px;background:#7C4DAD;color:#fff;font-size:12px;box-shadow:inset 0 1px 0 rgba(255,255,255,.4)}
.home .pane-h{display:flex;align-items:center;justify-content:space-between;font-size:var(--text-sm);font-weight:700;color:var(--text-strong);margin-bottom:var(--s3)}
.home .row{display:flex;align-items:center;justify-content:space-between;padding:9px 0;border-top:1px solid var(--stroke);font-size:var(--text-sm)}
.home .row:first-of-type{border-top:0}
.home .row .nm{color:var(--text-strong);font-weight:600}
.home .row .vl{font-family:var(--font-mono);color:var(--text-subtle)}
.home .bar{height:7px;border-radius:99px;background:var(--sky-100);overflow:hidden;margin-top:7px}
.home .bar i{display:block;height:100%;border-radius:99px;background:var(--sky-500)}

/* logo strip */
.home .strip{border-block:1px solid var(--stroke);background:var(--surface);padding:var(--s5) 0}
.home .strip-in{display:flex;align-items:center;gap:var(--s6);flex-wrap:wrap;justify-content:center;font-size:var(--text-sm);color:var(--text-subtle)}
.home .strip b{color:var(--text-strong);font-weight:700}

/* pillar overview */
.home .pillars{display:grid;grid-template-columns:1.55fr 1fr 1fr;gap:var(--s4)}
.home .pcard{background:var(--surface);border:1px solid var(--stroke);border-radius:var(--r-lg);padding:var(--s6);display:flex;flex-direction:column;gap:var(--s3);box-shadow:var(--shadow-sm);transition:.18s}
.home .pcard:hover{box-shadow:var(--shadow-md);transform:translateY(-2px)}
.home .pcard .kicker{font-size:var(--text-label);letter-spacing:var(--tracking-label);text-transform:uppercase;font-weight:700}
.home .pcard h3{font-size:var(--text-h3)}
.home .pcard p{font-size:var(--text-sm);color:var(--text-subtle)}
.home .pcard .more{margin-top:auto;padding-top:var(--s4);font-size:var(--text-sm);font-weight:600}
.home .pcard.flag{grid-row:span 1;background:linear-gradient(165deg,#fff, var(--cosec-tint));border-color:var(--sky-200)}
.home .pcard.flag .kicker{color:var(--cosec-accent)}
.home .pcard.tools .kicker{color:var(--tools-ink)}
.home .pcard.recap .kicker{color:var(--amber-600)}
.home .rule{width:34px;height:3px;border-radius:99px}

/* ---------- COMPANY SECRETARY (flagship) ---------- */
.home .flagship{background:var(--fog);border-block:1px solid var(--stroke)}
.home .two{display:grid;grid-template-columns:1fr 1fr;gap:var(--s8);align-items:start}
.home .feat{display:flex;gap:var(--s4);padding:var(--s5) 0;border-top:1px solid var(--stroke-strong)}
.home .feat:last-child{border-bottom:1px solid var(--stroke-strong)}
/* Scaled-down clay treatment on the index badges — navy gradient keeps the
   flagship Company Secretary section serious/calm while matching the puffy
   dimensional style used on the productivity tiles. */
.home .feat .ix{width:34px;height:34px;flex:none;border-radius:11px;border:none;display:grid;place-items:center;font-family:var(--font-mono);font-size:12px;font-weight:600;color:#fff;
  background:linear-gradient(158deg, color-mix(in srgb, var(--cosec) 60%, #fff) 0%, var(--cosec) 70%, color-mix(in srgb, var(--cosec) 88%, #000) 100%);
  box-shadow:0 6px 13px -4px rgba(35,58,85,.42), 0 2px 4px -1px rgba(35,58,85,.28), inset 0 1.5px 0 rgba(255,255,255,.38), inset 0 -2px 5px -1px rgba(12,24,38,.35)}
.home .feat h4{font-size:var(--text-base)}
.home .feat p{font-size:var(--text-sm);color:var(--text-subtle);margin-top:4px}

/* signature: atomic register sync */
.home .atomic{background:var(--surface);border:1px solid var(--stroke);border-radius:var(--r-lg);padding:var(--s5);box-shadow:var(--shadow-md)}
.home .atomic-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--s4)}
.home .atomic-head h4{font-size:var(--text-sm)}
.home .atomic-body{display:grid;grid-template-columns:1fr 26px 1fr;gap:var(--s3);align-items:center}
.home .mini{border:1px solid var(--stroke);border-radius:var(--r-md);padding:var(--s4);background:var(--surface-sunk)}
.home .mini .lbl{font-size:var(--text-label);letter-spacing:var(--tracking-label);text-transform:uppercase;font-weight:700;color:var(--text-subtle);margin-bottom:var(--s3)}
.home .kv{display:flex;justify-content:space-between;font-size:var(--text-sm);padding:5px 0;font-family:var(--font-mono);color:var(--text-body)}
.home .kv b{font-family:var(--font-body);font-weight:600;color:var(--text-strong)}
.home .link-mark{display:grid;place-items:center;color:var(--sky-500)}
.home .link-mark div{width:2px;height:56px;background:linear-gradient(var(--sky-200),var(--sky-500),var(--sky-200));border-radius:2px}
.home .atomic-foot{margin-top:var(--s4);padding-top:var(--s3);border-top:1px dashed var(--stroke-strong);display:flex;align-items:center;gap:var(--s2);font-size:var(--text-sm);color:var(--text-subtle)}

/* signature: compliance timeline */
.home .timeline{margin-top:var(--s5);background:var(--surface);border:1px solid var(--stroke);border-radius:var(--r-lg);padding:var(--s5);box-shadow:var(--shadow-sm)}
.home .tl-track{position:relative;margin-top:var(--s5);padding-top:var(--s5);border-top:2px solid var(--stroke)}
.home .tl-months{display:grid;grid-template-columns:repeat(6,1fr);font-size:var(--text-label);letter-spacing:.1em;text-transform:uppercase;color:var(--text-subtle);font-weight:700}
.home .tl-items{display:grid;grid-template-columns:repeat(6,1fr);gap:var(--s2);margin-top:var(--s3)}
.home .tl-i{font-size:var(--text-sm);border-radius:var(--r-xs);padding:7px 9px;line-height:1.35;font-weight:600}
.home .tl-i.a{background:var(--sky-100);color:var(--sky-700)}
.home .tl-i.b{background:var(--warn-tint);color:var(--amber-600)}
.home .tl-i.c{background:var(--ok-tint);color:#0A7B60}
.home .tl-i.ghost{background:var(--surface-sunk);color:var(--text-subtle);font-weight:500}

/* ---------- PRODUCTIVITY ---------- */
.home .tiles{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--s3)}
/* Each tile carries its own accent via --tc (colour) / --tc-tint. The default
   is teal (--tools); .t-coral / .t-violet / .t-mint / .t-rose override it so
   the five-tile row rotates through the supplementary palette instead of being
   one flat block of blue-green. */
.home .tile{--tc:var(--tools);--tc-tint:var(--tools-tint);background:var(--surface);border:1px solid var(--stroke);border-radius:var(--r-md);padding:var(--s5) var(--s4);transition:.16s;box-shadow:var(--shadow-xs)}
.home .tile.t-coral{--tc:var(--sup-coral);--tc-tint:var(--sup-coral-tint)}
.home .tile.t-violet{--tc:var(--sup-violet);--tc-tint:var(--sup-violet-tint)}
.home .tile.t-mint{--tc:var(--sup-mint);--tc-tint:var(--sup-mint-tint)}
.home .tile.t-rose{--tc:var(--sup-rose);--tc-tint:var(--sup-rose-tint)}
.home .tile:hover{border-color:var(--tc);box-shadow:var(--shadow-md);transform:translateY(-2px)}
/* Soft "clay" icon tile: a rounded-square, matte top-to-bottom gradient in the
   tile's accent, lifted by a colour-tinted outer drop shadow and read as raised
   by an inset top highlight + a soft inset bottom shade. */
.home .tile .ic{
  width:48px;height:48px;border-radius:15px;
  display:grid;place-items:center;margin-bottom:var(--s4);
  background:linear-gradient(158deg,
    color-mix(in srgb, var(--tc) 82%, #fff) 0%,
    var(--tc) 58%,
    color-mix(in srgb, var(--tc) 90%, #000) 100%);
  box-shadow:
    0 8px 16px -4px color-mix(in srgb, var(--tc) 38%, transparent),
    0 2px 4px -1px color-mix(in srgb, var(--tc) 30%, transparent),
    inset 0 1.5px 0 rgba(255,255,255,.55),
    inset 0 -3px 6px -1px color-mix(in srgb, var(--tc) 55%, #000 12%);
  transition:transform .16s ease, box-shadow .16s ease;
}
.home .tile:hover .ic{
  transform:translateY(-2px);
  box-shadow:
    0 12px 22px -4px color-mix(in srgb, var(--tc) 46%, transparent),
    0 3px 6px -1px color-mix(in srgb, var(--tc) 32%, transparent),
    inset 0 1.5px 0 rgba(255,255,255,.6),
    inset 0 -3px 6px -1px color-mix(in srgb, var(--tc) 55%, #000 12%);
}
.home .tile h4{font-size:var(--text-sm)}
.home .tile p{font-size:var(--text-sm);color:var(--text-subtle);margin-top:3px}
/* White glyph reads as the raised element on the coloured clay tile; a faint
   drop-shadow lifts it off the lighter top of the gradient for legibility. */
.home svg.i{width:21px;height:21px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 1px 1.5px rgba(20,30,45,.22))}

/* ---------- WORK RECAP ---------- */
.home .recap-sec{background:linear-gradient(170deg,var(--sand-50),#F4F9FF 70%);border-block:1px solid var(--stroke)}
.home .share-card{background:var(--ink-900);border-radius:var(--r-lg);padding:var(--s6);color:#fff;box-shadow:var(--shadow-lg);position:relative;overflow:hidden}
.home .share-card::after{content:"";position:absolute;right:-60px;top:-60px;width:220px;height:220px;border-radius:50%;background:radial-gradient(closest-side,rgba(87,164,250,.45),transparent)}
.home .share-card .yr{font-family:var(--font-mono);font-size:var(--text-sm);letter-spacing:.16em;color:var(--sky-300);text-transform:uppercase}
.home .share-card h3{font-family:var(--font-display);font-weight:400;color:#fff;font-size:2rem;margin-top:var(--s3);line-height:1.15}
.home .share-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4);margin-top:var(--s6);padding-top:var(--s5);border-top:1px solid rgba(255,255,255,.16)}
.home .share-stats .n{font-family:var(--font-display);font-size:1.75rem;color:#fff}
.home .share-stats .l{font-size:var(--text-sm);color:rgba(255,255,255,.6);margin-top:2px}
.home .share-quote{margin-top:var(--s5);font-size:var(--text-sm);color:rgba(255,255,255,.82);line-height:1.6;position:relative}

/* pricing */
.home .price-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4)}
.home .plan{background:var(--surface);border:1px solid var(--stroke);border-radius:var(--r-lg);padding:var(--s6);display:flex;flex-direction:column;box-shadow:var(--shadow-sm)}
.home .plan.hi{border:1.5px solid var(--sky-500);box-shadow:var(--shadow-md);position:relative}
.home .plan .tag{position:absolute;top:-11px;left:var(--s6);background:var(--sky-600);color:#fff;font-size:var(--text-label);letter-spacing:.1em;text-transform:uppercase;font-weight:700;padding:4px 10px;border-radius:var(--r-pill)}
.home .plan h3{font-size:var(--text-h3)}
.home .plan .amt{font-family:var(--font-display);font-size:2.4rem;color:var(--text-strong);margin:var(--s4) 0 2px}
.home .plan .per{font-size:var(--text-sm);color:var(--text-subtle)}
.home .plan ul{list-style:none;padding:0;margin:var(--s5) 0 var(--s6);display:flex;flex-direction:column;gap:var(--s3);font-size:var(--text-sm)}
.home .plan li{display:flex;gap:9px;align-items:flex-start}
.home .plan li::before{content:"";width:15px;height:15px;flex:none;margin-top:3px;border-radius:50%;background:var(--sky-100) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230A66D0' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/9px no-repeat}
.home .plan .btn{margin-top:auto;justify-content:center}

/* trust note */
.home .trust{background:var(--surface);border:1px solid var(--stroke);border-left:none;border-radius:var(--r-lg);padding:var(--s6);display:grid;grid-template-columns:auto 1fr;gap:var(--s5);box-shadow:var(--shadow-xs)}
/* Light clay tile: puffy raised look while keeping the dark navy shield glyph
   (inline stroke #233A55) legible on a pale sky ground. */
.home .trust .seal{width:44px;height:44px;border-radius:14px;display:grid;place-items:center;
  background:linear-gradient(158deg,#fff 0%,var(--cosec-tint) 100%);
  border:1px solid var(--stroke);
  box-shadow:0 7px 15px -5px rgba(35,58,85,.24), inset 0 1.5px 0 rgba(255,255,255,.9), inset 0 -3px 6px -2px rgba(35,58,85,.14)}
.home .trust p{font-size:var(--text-sm);color:var(--text-subtle)}

/* final cta */
.home .final{background:var(--ink-900);color:#fff;border-radius:var(--r-xl);padding:var(--s9) var(--s8);text-align:center;position:relative;overflow:hidden}
.home .final::before{content:"";position:absolute;inset:auto -10% -60% -10%;height:300px;background:radial-gradient(closest-side,rgba(34,134,240,.4),transparent)}
.home .final h2{font-family:var(--font-display);font-weight:400;color:#fff;font-size:var(--text-h1);position:relative}
.home .final p{color:rgba(255,255,255,.72);margin:var(--s4) auto 0;max-width:52ch;position:relative}
.home .final .hero-cta{justify-content:center;position:relative}
.home .final .btn-ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.28)}
.home .final .btn-ghost:hover{border-color:#fff;color:#fff}

.home footer{padding:var(--s8) 0 var(--s7);border-top:1px solid var(--stroke);margin-top:var(--s9);font-size:var(--text-sm)}
.home .foot-grid{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:var(--s6)}
.home .foot-grid h5{font-size:var(--text-sm);text-transform:uppercase;letter-spacing:var(--tracking-label);color:var(--text-subtle);margin:0 0 var(--s4);font-weight:700}
.home .foot-grid ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:10px}
.home .foot-grid a{color:var(--text-body);font-size:var(--text-sm)}
.home .foot-grid a:hover{color:var(--sky-600)}
.home .foot-base{margin-top:var(--s7);padding-top:var(--s5);border-top:1px solid var(--stroke);display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--s3);font-size:var(--text-sm);color:var(--text-subtle)}

@media(max-width:960px){
  .home .hero-grid,.home .two{grid-template-columns:1fr}
  .home .stack{height:380px}
  .home .pillars,.home .price-grid{grid-template-columns:1fr}
  .home .tiles{grid-template-columns:repeat(2,1fr)}
  .home .tl-months,.home .tl-items{grid-template-columns:repeat(3,1fr)}
  .home .foot-grid{grid-template-columns:1fr 1fr}
}
/* ---- end homepage (sky / modular) component classes ---- */

/* ---- working / in-progress indicator ----------------------------------
   One shared spinner for every "we are doing something" state, so a slow
   request never looks like a frozen one. Two ways to use it:

     <span class="spin" aria-hidden="true"></span>   an explicit element
     <p class="is-working">載入緊…</p>                 auto-prefixed text

   It draws in currentColor and sizes off the local font-size, so it inherits
   whatever it sits in rather than needing a variant per context.

   The animation is decorative: it is aria-hidden, and the surrounding text
   already states what is happening, so a screen reader loses nothing.
   ---- */
.spin,
.is-working::before {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  border: 2px solid currentColor;
  /* One transparent quadrant is what makes the rotation legible. */
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: -0.1em;
  flex: none;
}

.is-working::before {
  content: "";
  margin-right: 0.5em;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* A button that is mid-request: spinner before the label, and not clickable
   again while it runs. */
.btn[data-busy="true"],
button[data-busy="true"] {
  position: relative;
  pointer-events: none;
  opacity: 0.75;
}

.btn[data-busy="true"]::before,
button[data-busy="true"]::before {
  content: "";
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.5em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: -0.1em;
}

/* Spinning is exactly the kind of motion this setting is meant to stop.
   Keep an indicator -- a soft pulse -- so the state is still visible. */
@media (prefers-reduced-motion: reduce) {
  .spin,
  .is-working::before,
  .btn[data-busy="true"]::before,
  button[data-busy="true"]::before {
    animation: working-pulse 1.4s ease-in-out infinite;
    border-top-color: currentColor;
  }

  @keyframes working-pulse {
    50% {
      opacity: 0.25;
    }
  }
}
/* ---- end working / in-progress indicator ---- */

/* ---- NNC1 review fixes: shared motion primitives (I1, I4, I7) ----
   A5/R1/R2/R3's actual property values live in nnc1.html's and
   nnc1-form.html's own page-level <style> blocks (they override selectors
   already declared there, and inline page styles load after this file, so
   editing this file alone would not have taken effect). Only the new,
   NNC1-only animation classnames below are added here, since nothing else
   defines them and the reduced-motion override must live in the same
   cascade layer as the animation it disables. */

/* I7: crossfade re-rendered secretary/director blocks instead of a hard
   layout jump. */
.nnc1-refresh-fade {
  animation: nnc1-crossfade 0.15s ease;
}

@keyframes nnc1-crossfade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* I4: 600ms background flash on a chat-patched field/section. */
.nnc1-field-flash {
  animation: nnc1-field-flash 0.6s ease;
}

@keyframes nnc1-field-flash {
  0% {
    background-color: rgba(43, 127, 214, 0.18);
  }
  100% {
    background-color: transparent;
  }
}

/* I1: three-dot "thinking" bubble pulse. */
.nnc1-thinking-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: 0 2px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.3;
  animation: nnc1-thinking-pulse 1s ease-in-out infinite;
}

.nnc1-thinking-dot:nth-child(2) {
  animation-delay: 0.15s;
}

.nnc1-thinking-dot:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes nnc1-thinking-pulse {
  0%,
  80%,
  100% {
    opacity: 0.3;
  }
  40% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nnc1-refresh-fade {
    animation: none;
  }

  .nnc1-field-flash {
    animation: none;
    background-color: rgba(43, 127, 214, 0.18);
  }

  .nnc1-thinking-dot {
    animation: none;
    opacity: 0.6;
  }

  .nnc1-chat-panel {
    transition: none;
  }
}
/* ---- end NNC1 review fixes ---- */
