/* ==========================================================================
   WellBridge AI — stylesheet
   --------------------------------------------------------------------------
   Hand-written. This file is the design lever; build.py never touches it.

   Colour, type and logo rules come from the brand specification
   (wellbridge/WellBridge-AI-Website-Design.pdf, pages 02-05). The five brand
   colours are used exactly as specified. The neutral greys are NOT: the
   specification's #68736F and #C9C5BB are print values that measure 4.35:1 and
   1.53:1 on warm ivory, so the screen build substitutes tuned equivalents that
   clear WCAG AA. See README.md, "Deviations from the specification".

   Layout: mobile-first. Every rule below the responsive block is a desktop
   enhancement, so the narrow layout is the one that is always correct.
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */

:root {
  /* Brand — from page 05 of the specification. Do not alter. */
  --evergreen: #075e59;
  --graphite: #17211f;
  --ivory: #f3f1eb;
  --white: #ffffff;
  --copper: #9b5b32;

  /* Derived from the brand colours, for interaction states only. */
  --evergreen-deep: #05463f;
  --evergreen-wash: #e1ece8;
  --copper-wash: #f0e6de;

  /* Text. --ink and --muted are specified; --caption is screen-tuned. */
  --ink: #17211f;
  --muted: #4e5b57;
  --caption: #646f6b;      /* 4.62:1 on ivory, was #68736F at 4.35:1 */
  --caption-dark: #808b87; /* 4.68:1 on graphite */

  /* Lines. --line is decorative; --field carries a control boundary and so
     must clear the 3:1 non-text minimum. */
  --line: #d9d5cb;
  --border: #c4bfb4;
  --field: #8c8981;
  --wash: #e9e6de;

  /* Type. The specification names Zodiak and Satoshi, both licensed faces,
     and allows an approved substitute. They are listed first so a licensed
     install is picked up automatically; the rest of each stack is the
     approved substitute. Nothing is fetched from a third party. */
  /* The CJK faces at the end of each stack are named for the same reason the
     Latin ones are: a browser only falls back on its own default if it is
     allowed to choose, and its choice for Chinese is often a print-era serif.
     Naming the system faces keeps headings on a humanist sans in all three
     trees. Nothing here is downloaded -- these are installed faces, and a
     machine without them falls through to the generic family as before. */
  --font-display: "Zodiak", "Playfair Display", Georgia, "Times New Roman",
    "PingFang HK", "Microsoft JhengHei", "Microsoft YaHei", "Noto Sans CJK HK",
    "Noto Sans CJK SC", serif;
  --font-sans: "Satoshi", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, "PingFang HK", "Microsoft JhengHei",
    "Microsoft YaHei", "Noto Sans CJK HK", "Noto Sans CJK SC", sans-serif;
  --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;

  /* Metrics. Clear space around the mark is one pillar width; at the sizes
     used here that resolves to roughly 8px, applied via .brand padding. */
  --wrap: 1120px;
  --wrap-narrow: 760px;
  --radius: 2px;
  --header-h: 68px;
}

/* --- Reset -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ivory);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1rem;          /* the 16px floor -- page 04: "Body copy should
                               remain at least 16 px online". Do not drop this
                               below 1rem: it is a stated acceptance criterion,
                               not a preference. Shrink the headings instead. */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  margin: 0 0 0.6em;
  letter-spacing: -0.01em;
}

/* Display type, reduced ~15% from the first build. Body copy is NOT part of
   this reduction: page 04 of the specification says "Body copy should remain
   at least 16 px online", and `body` sits exactly on that floor at 1rem. The
   headings were where the size actually read as too large, so they carry the
   whole reduction. The lower bound of each clamp is held above 1rem so a
   heading never falls to body size on a narrow screen. */
h1 { font-size: clamp(1.95rem, 1.25rem + 2.75vw, 3.05rem); }
h2 { font-size: clamp(1.5rem, 1.05rem + 1.75vw, 2.2rem); }

/* A heading that wraps leaves one word alone on the last line at some widths,
   and at this size a single word looks like a mistake rather than a line
   break. `balance` evens the lines instead of filling the first one. Scoped to
   h1/h2 -- on a long paragraph it can force an unwanted break, and short
   labels like the KPI captions gain nothing. */
h1, h2 { text-wrap: balance; }
@supports not (text-wrap: balance) {
  h1, h2 { text-wrap: pretty; }
}
h3 { font-size: clamp(1.05rem, 0.97rem + 0.5vw, 1.24rem); }
h4 { font-size: 1rem; }

/* Chinese, in either script. A CJK glyph fills its em box far more completely
   than a Latin letter does, so the same measure and the same negative tracking
   that suit English set noticeably denser here. The display faces also carry no
   CJK glyphs at all, so headings fall through to the system faces named in the
   stacks above -- these two rules are what make them sit correctly.
   :lang(zh) matches zh-HK and zh-CN both; the two blocks below it pick the
   face for the script, since the Traditional and Simplified system fonts are
   different files with different letterforms. */
:lang(zh) h1,
:lang(zh) h2,
:lang(zh) h3 { line-height: 1.3; letter-spacing: 0; }

:lang(zh) p,
:lang(zh) li,
:lang(zh) .lede { line-height: 1.75; }

/* The kicker is upper-cased Latin with 0.18em of tracking. Upper-casing does
   nothing to Chinese, and the tracking needs a little more room. */
:lang(zh) .kicker { letter-spacing: 0.22em; }

/* Preferred system faces per script: JhengHei is the Traditional face, YaHei
   the Simplified one. Both fonts contain both scripts, so without this the
   Simplified tree would render in Traditional-styled letterforms. */
:lang(zh-CN) {
  --font-display: "Zodiak", "Playfair Display", Georgia, "Times New Roman",
    "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", serif;
  --font-sans: "Satoshi", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, "Microsoft YaHei", "PingFang SC",
    "Noto Sans CJK SC", sans-serif;
}

p { margin: 0 0 1.1em; max-width: 68ch; color: var(--muted); }
h1 + p, h2 + p, h3 + p { color: var(--muted); }

a { color: var(--evergreen); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--evergreen-deep); }

strong, b { color: var(--ink); font-weight: 600; }

hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

:focus-visible {
  outline: 3px solid var(--evergreen);
  outline-offset: 2px;
  border-radius: var(--radius);
}

::selection { background: var(--evergreen-wash); color: var(--ink); }

/* Anchors must not land under the sticky header. */
[id] { scroll-margin-top: calc(var(--header-h) + 16px); }

/* --- Layout ------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.wrap-narrow { max-width: var(--wrap-narrow); }

.section { padding-block: 4rem; }
.section-tight { padding-block: 2.5rem; }
.section-wash { background: var(--wash); }
.section-white { background: var(--white); }
.section-dark { background: var(--graphite); color: var(--ivory); }
.section-dark h2, .section-dark h3 { color: var(--ivory); }
.section-dark p { color: #c3cbc7; }
.section-dark a { color: var(--ivory); }

.kicker {
  display: block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--evergreen);
  margin-bottom: 0.9rem;
}

.section-dark .kicker { color: #7fb3ab; }

.lede { font-size: 1.05rem; color: var(--muted); max-width: 62ch; }

/* --- Skip link ---------------------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--evergreen);
  color: var(--white);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* --- Header ------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--white);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  min-height: var(--header-h);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* space-between rather than margin-left:auto on the nav. Both put the nav
     hard right when the two share a row, but when the nav is too wide to fit
     beside the logo it wraps -- and space-between leaves that second row
     flush left, where an auto margin would strand the nav on the right. */
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-block: 0.65rem;
}

/* Clear space: one pillar width around the mark, per page 10. */
.brand {
  display: inline-flex;
  align-items: center;
  padding: 0.5rem;
  margin-left: -0.5rem;
  flex: 0 0 auto;
}
.brand img { display: block; width: 188px; }

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.35rem;
  font-size: 0.95rem;
}

.site-nav a {
  color: var(--ink);
  text-decoration: none;
  padding: 0.35rem 0;
  border-bottom: 2px solid transparent;
}
.site-nav a:hover { border-bottom-color: var(--evergreen); color: var(--evergreen); }
.site-nav a[aria-current="page"] { color: var(--evergreen); border-bottom-color: var(--evergreen); }

/* Client Login stays visible but secondary, per page 06. */
.site-nav .nav-login {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.85rem;
  color: var(--muted);
  font-size: 0.9rem;
}
.site-nav .nav-login:hover { border-color: var(--evergreen); color: var(--evergreen); }
.site-nav .nav-login[aria-current="page"] { border-color: var(--evergreen); color: var(--evergreen); }

/* The nav and the language switcher share the right-hand side of the bar.
   Wrapping them in one flex item keeps the brand hard left and the nav hard
   right, which is the page-06 layout; without the wrapper, space-between would
   push the nav into the middle to make room for the switcher. */
.header-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem 1.5rem;
}

/* Language switcher. Each language is named in its own script -- "Chinese
   (Traditional)" is no use to someone who reads Chinese. The language you are
   already reading is not a link, because it points at the page you are on. */
.lang-switch {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.9rem;
  font-size: 0.85rem;
}

.lang-switch a,
.lang-switch .lang-current { padding: 0.35rem 0; }

.lang-switch a { color: var(--muted); text-decoration: none; }
.lang-switch a:hover { color: var(--evergreen); text-decoration: underline; }

.lang-switch .lang-current {
  color: var(--evergreen);
  font-weight: 600;
}

/* Only rule the switcher off from the nav when there is room for it to sit on
   the same line; wrapped onto its own row, a leading border reads as a stray
   vertical line. */
@media (min-width: 900px) {
  .lang-switch {
    padding-left: 1.1rem;
    border-left: 1px solid var(--line);
  }
}

/* --- Buttons ------------------------------------------------------------ */

.btn {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.85rem 1.4rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn-primary { background: var(--evergreen); color: var(--white); }
.btn-primary:hover { background: var(--evergreen-deep); color: var(--white); }

.btn-ghost { background: transparent; color: var(--evergreen); border-color: var(--evergreen); }
.btn-ghost:hover { background: var(--evergreen); color: var(--white); }

.btn-on-dark { background: var(--ivory); color: var(--graphite); }
.btn-on-dark:hover { background: var(--white); color: var(--graphite); }

/* `.section-dark a` up at the top of this file is (0,1,1) -- one class plus one
   type -- while a bare `.btn-on-dark` is (0,1,0). On a dark band the band's link
   colour therefore won the cascade and this button painted an ivory label onto
   its own ivory fill: a 1:1 contrast ratio, which is to say a blank rectangle
   where the site's primary call to action should be. Measured on the live site
   before this rule existed, on every dark CTA band in all three languages.
   Repeating the ancestor lifts the rule to (0,2,1) so it wins.
   Do NOT "simplify" this by adding :not(.btn) to the `.section-dark a` rule
   instead -- `.btn-ghost` also carries `.btn`, and it relies on that rule for
   its ivory label against the graphite band (14.6:1). Excluding it would drop
   the ghost button to its evergreen base colour on a near-black background. */
.section-dark a.btn-on-dark,
.section-dark a.btn-on-dark:hover { color: var(--graphite); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }

/* --- Hero --------------------------------------------------------------- */

.hero { padding-block: 3.5rem 4rem; }

.hero-grid { display: grid; gap: 2.5rem; align-items: center; }

.hero h1 { margin-bottom: 0.5em; }

/* The specification's homepage mock pairs the headline with a geometric
   panel: a soft gradient carrying a skewed evergreen portal. Rebuilt here
   in CSS rather than shipped as an image. */
.art {
  position: relative;
  min-height: 260px;
  border-radius: var(--radius);
  background: linear-gradient(145deg, #dfe8e4, #8ba9a2);
  overflow: hidden;
}
.art::before {
  content: "";
  position: absolute;
  inset: 26% 8% 10% 22%;
  border: 3px solid var(--evergreen);
  border-bottom: 0;
  transform: skewX(-18deg);
}

/* --- Cards and grids ---------------------------------------------------- */

.grid { display: grid; gap: 1.5rem; }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: 1fr; }

.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.75rem;
}
.card h3 { margin-bottom: 0.5rem; }
.card p:last-child { margin-bottom: 0; }
.card-dark { background: var(--graphite); border-color: var(--graphite); }
.card-dark h3 { color: var(--ivory); }
.card-dark p { color: #c3cbc7; }

.card-link { text-decoration: none; color: inherit; display: block; }
.card-link:hover { border-color: var(--evergreen); }
.card-link:hover h3 { color: var(--evergreen); }

.card-tag {
  display: block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--copper);       /* restrained editorial detail, per page 02 */
  margin-bottom: 0.65rem;
}

.card-cta {
  display: inline-block;
  margin-top: 1rem;
  font-weight: 600;
  font-size: 0.95rem;
}

/* --- Process steps ------------------------------------------------------ */

.steps { counter-reset: step; display: grid; gap: 1.25rem; }

.step {
  background: var(--white);
  border-top: 3px solid var(--evergreen);
  border-radius: var(--radius);
  padding: 1.5rem;
}
.step-num {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--copper);
  letter-spacing: 0.08em;
  margin-bottom: 0.5rem;
}
.step h3 { font-size: 1.08rem; margin-bottom: 0.4rem; }
.step p { font-size: 0.95rem; margin-bottom: 0; }

/* --- Engagement flow (Home -> Service detail -> Consultation -> Follow-up) */

.flow { display: grid; gap: 0.75rem; }

.flow-step {
  border-top: 2px solid var(--evergreen);
  padding-top: 0.9rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
}
.flow-step span {
  display: block;
  font-weight: 400;
  font-size: 0.88rem;
  color: var(--muted);
  margin-top: 0.25rem;
}

/* --- Page header -------------------------------------------------------- */

.page-head { background: var(--graphite); color: var(--ivory); padding-block: 3.5rem 3rem; }
.page-head h1 { color: var(--ivory); margin-bottom: 0.35em; }
.page-head p { color: #c3cbc7; font-size: 1.1rem; margin-bottom: 0; }
.page-head .kicker { color: #7fb3ab; }

.breadcrumb {
  font-size: 0.85rem;
  color: var(--caption-dark);
  margin-bottom: 1.5rem;
}
.breadcrumb a { color: var(--caption-dark); }
.breadcrumb a:hover { color: var(--ivory); }
.breadcrumb .crumb-sep { margin-inline: 0.5rem; }
/* build.py emits the final crumb as <span class="crumb-here"> rather than a
   link, because you cannot navigate to the page you are already on. Without a
   rule it inherited the muted link colour, so the current page looked exactly
   like its clickable ancestors. Lift it and weight it so the trail reads as
   "where you are" rather than three identical links. */
.breadcrumb .crumb-here {
  color: var(--ivory);
  font-weight: 600;
}

/* --- Notices ------------------------------------------------------------ */

/* Used for the reader-facing disclosures (illustrative figures, sign-in not
   yet open, what the privacy page collects). Copper is the specification's
   editorial accent and is reserved for exactly this. */
.notice {
  background: var(--copper-wash);
  border-left: 3px solid var(--copper);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  margin-block: 1.5rem;
}
.notice h3 { font-size: 1rem; margin-bottom: 0.4rem; color: var(--ink); }
.notice p { font-size: 0.92rem; margin-bottom: 0.5rem; }
.notice p:last-child { margin-bottom: 0; }
.notice ul { margin: 0.5rem 0 0; padding-left: 1.2rem; font-size: 0.92rem; color: var(--muted); }
.notice li { margin-bottom: 0.3rem; }

.notice-quiet {
  background: var(--wash);
  border-left-color: var(--field);
}

/* --- Feature list ------------------------------------------------------- */

.checks { list-style: none; margin: 0 0 1.1rem; padding: 0; }
.checks li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: 0.6rem;
  color: var(--muted);
}
.checks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--evergreen);
}

/* --- Packages ----------------------------------------------------------- */

.package { display: flex; flex-direction: column; }
.package h3 { margin-bottom: 0.35rem; }
.package .package-for {
  font-size: 0.85rem;
  color: var(--caption);
  margin-bottom: 1rem;
}
.package .card-cta { margin-top: auto; padding-top: 1rem; }

/* --- Portal mock (page 09) --------------------------------------------- */

.portal {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.portal-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: var(--white);
}
.portal-bar .portal-name { font-weight: 700; color: var(--evergreen); font-size: 0.95rem; }
.portal-bar .portal-tier { font-size: 0.8rem; color: var(--caption); }

.portal-body { display: grid; grid-template-columns: 1fr; }

.portal-side {
  background: var(--graphite);
  color: #c3cbc7;
  padding: 1.25rem;
  font-size: 0.9rem;
}
.portal-side ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.portal-side li[aria-current] { color: var(--ivory); font-weight: 600; }

.portal-main { padding: 1.5rem; }
.portal-main h3 { margin-bottom: 1rem; font-size: 1.1rem; }

/* minmax(0, 1fr) rather than a bare `1fr`. A bare `1fr` is `minmax(auto, 1fr)`,
   so each track's minimum is its content's min-content width -- three KPI tiles
   forced side by side at every viewport, with nothing able to shrink below its
   longest word. The 0 lets the tracks actually compress on a narrow phone. */
.kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; margin-bottom: 1.25rem; }
/* Column flex with the space pushed between label and value, so the numerals
   sit on a common baseline across the row. They are <b> blocks under a label
   that wraps to two lines in some languages and one in others ("進行中項目"
   fits, "Active projects" does not), and without this the three figures landed
   at three different heights -- the row read as misaligned rather than as
   three tiles. */
.kpi {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem;
  font-size: 0.8rem;
  color: var(--caption);
}
.kpi b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.7rem;
  line-height: 1.1;
  color: var(--ink);
}

.progress-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem;
}
.progress-label { font-weight: 600; color: var(--ink); font-size: 0.95rem; }
.progress-track {
  height: 8px;
  background: var(--wash);
  border-radius: 999px;
  margin: 0.75rem 0 0.6rem;
  overflow: hidden;
}
.progress-fill { height: 100%; width: 68%; background: var(--evergreen); border-radius: 999px; }
.progress-note { font-size: 0.85rem; color: var(--caption); margin: 0; }

/* --- Forms -------------------------------------------------------------- */

.form { display: grid; gap: 1.1rem; max-width: 640px; }
.field { display: grid; gap: 0.4rem; }
.field label { font-weight: 600; font-size: 0.92rem; color: var(--ink); }
.field .hint { font-size: 0.85rem; color: var(--caption); }

.field input,
.field select,
.field textarea {
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--field);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  width: 100%;
}
.field textarea { min-height: 140px; resize: vertical; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 3px solid var(--evergreen);
  outline-offset: 1px;
  border-color: var(--evergreen);
}

.field-row { display: grid; gap: 1.1rem; }

.form-status {
  border-left: 3px solid var(--evergreen);
  background: var(--evergreen-wash);
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  font-size: 0.95rem;
}
.form-status[hidden] { display: none; }

/* --- Footer ------------------------------------------------------------- */

.site-footer {
  background: var(--graphite);
  color: #c3cbc7;
  padding-block: 3rem 2rem;
  font-size: 0.92rem;
}
.site-footer a { color: var(--ivory); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

.footer-grid { display: grid; gap: 2rem; margin-bottom: 2.5rem; }
.footer-brand img { width: 176px; display: block; margin-bottom: 1rem; }
.footer-brand p { color: var(--caption-dark); font-size: 0.88rem; max-width: 34ch; }

.footer-col h2 {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--caption-dark);
  margin-bottom: 1rem;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }

.footer-base {
  border-top: 1px solid #2c3733;
  padding-top: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: space-between;
  color: var(--caption-dark);
  font-size: 0.85rem;
}
.footer-base p { color: inherit; margin: 0; max-width: none; }

/* --- 404 ---------------------------------------------------------------- */

.notfound { text-align: center; padding-block: 6rem; }
.notfound p { margin-inline: auto; }

/* --- Responsive --------------------------------------------------------- */

@media (min-width: 640px) {
  .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .field-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  .section { padding-block: 5.5rem; }
  .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .flow { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .hero { padding-block: 5rem 6rem; }
  .hero-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: 4rem; }  /* page 06 ratio */
  .art { min-height: 380px; }

  .portal-body { grid-template-columns: 200px minmax(0, 1fr); }
  .footer-grid { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); }
  .brand img { width: 210px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Print -------------------------------------------------------------- */

@media print {
  .site-header, .site-footer, .skip, .art { display: none; }
  body { background: #fff; }
  .page-head { background: #fff; color: #000; }
  .page-head h1, .page-head p, .page-head .kicker { color: #000; }
}
