/*
 * M14 HiFi reference chrome (public shell conforming to
 * docs/design/.design-work/2026-09-05-m6b-platform-ui): header band + flat
 * nav + mobile menu + locale/theme controls, the reference button language,
 * the shared title-block treatment, the three-group footer rail and the
 * consent press box. Loaded on every public route right after public.css.
 *
 * The reference-derived composition values (header rhythm, footer rail
 * geometry, signal bar, button padding) are self-declared in the token block
 * below so this sheet stays self-contained under the UI-contract value
 * rules; design colors keep resolving through tokens.css (pair-exact).
 */
:root {
  /* M14 reference composition values (mirror the ui-016..021 screens) */
  --chrome-header-pad: 1.2rem 1rem;
  --chrome-wordmark-size: 1.6rem;
  --chrome-nav-gap: 0.75rem 1.2rem;
  --chrome-locale-pad: 0.5rem 0.7rem;
  --chrome-locale-size: 0.82rem;
  --chrome-menu-bar-gap: 5px;
  --chrome-menu-bar-w: 20px;
  --chrome-menu-bar-h: 2px;
  --chrome-menu-panel-top: 0.6rem;
  --chrome-menu-panel-min: 12rem;
  --chrome-menu-panel-pad: 1rem 1.2rem;
  --chrome-scrim: rgba(21, 25, 50, 0.3);
  --chrome-consent-shadow: 0 -1rem 3rem rgba(21, 25, 50, 0.14);
  --chrome-footer-margin-top: 3.4rem;
  --chrome-footer-pad-block: 1.8rem 3rem;
  --chrome-footer-brand-size: 1.1rem;
  --chrome-footer-bottom-gap: 1.3rem;
  --chrome-footer-mono-size: 0.76rem;
  --chrome-btn-pad: 0.55rem 1rem;
  --chrome-signal-w: 3rem;
  --chrome-signal-h: 2px;
  --chrome-title-pad-top: 1.1rem;
  --chrome-title-pad-bottom: 1.4rem;
  --chrome-title-size: clamp(2.25rem, 4vw, 3.45rem);
  --chrome-trail-margin: 0.2rem 0 0;
  --chrome-footer-pad: 3.25rem 1.5rem;
  --chrome-footer-gap: 2.5rem 4rem;
  --chrome-group-gap: 0.65rem;
  --chrome-link-min-height: 2.25rem;
  --chrome-bottom-pad: 1.25rem;
  --chrome-footer-pad-mobile: 2.5rem;
  --chrome-footer-gap-mobile: 2.25rem;
  --chrome-wordmark-mobile: 4rem;
  --chrome-languages-gap: 1.25rem;
  --chrome-min-target: 2.75rem; /* contract minimumTargetPx: 44 */
}

/* ---------- header (M14: HiFi reference chrome) ---------- */

/* position: relative anchors the mobile menu panel to the full-width header
   band, so the open menu is always bounded by the viewport (320+). The band
   closes with the frozen M11-B2 hairline. */
.public-header {
  position: relative;
  background: var(--color-bg);
  border-block-end: 1px solid var(--color-border);
}

.public-header-inner {
  display: flex;
  flex-wrap: wrap; /* 320/390: controls flow below the brand instead of clipping off-canvas */
  align-items: center;
  gap: var(--space-3) var(--space-6);
  padding-block: var(--chrome-header-pad);
}

.public-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--chrome-min-target);
  text-decoration: none;
  color: var(--color-text);
  border-radius: var(--radius-sm);
}

/* Reference wordmark: display face at 1.6rem/700 (smaller than the old
   --text-heading lock). */
.public-brand .brand-mark-word {
  font-size: var(--chrome-wordmark-size);
  font-weight: var(--weight-bold);
}

.public-nav {
  display: none;
  flex-wrap: wrap;
  gap: var(--chrome-nav-gap);
}

/* Reference flat nav: plain 44px inline links at body weight; the current
   surface carries the 3px inset accent underline. */
.public-nav .nav-link {
  padding: 0;
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  border-radius: 0;
}

.public-nav .nav-link[aria-current="page"] {
  box-shadow: inset 0 -3px 0 var(--color-accent);
  border-radius: 0;
}

.public-header-controls {
  display: flex;
  flex-wrap: wrap; /* each control group may drop to its own row instead of overflowing */
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-inline-start: auto;
}

/* Reference locale-toggle: the single conversion button (owner 2026-09-21:
   the retired EN · zh pair merged into one, keeping the same outlined square
   frame), mono code label in the owner-specified casing, no press shadow
   (the btn-secondary conformance block below supplies the outline itself). */
.public-header .locale-toggle {
  min-width: var(--chrome-min-target);
  padding: var(--chrome-locale-pad);
  font-family: var(--font-mono);
  font-size: var(--chrome-locale-size);
  line-height: 1;
  letter-spacing: 0.04em;
  box-shadow: none;
}

.public-header .locale-toggle:hover,
.public-header .locale-toggle:active {
  transform: none;
  box-shadow: none;
}

/* Reference theme-toggle presents as one icon-only outlined square; the
   tri-state menu behind it is live behavior (kept). The chevron and the
   1.5px control border give way to the reference button look. */
.public-header .menu-control[data-theme-control] > summary {
  min-width: var(--chrome-min-target);
  justify-content: center;
  padding-inline: var(--space-1);
  border: 2px solid var(--color-text);
  border-radius: var(--radius-sm);
}

.public-header .menu-control[data-theme-control] > summary::after { content: none; }

/* Frozen M11-B2 mobile chrome (`mobile-menu`): an icon-only 44px hamburger
   summary (three 20x2px ink bars) carrying the 選單 accessible name, a
   right-anchored panel under the toggle, and a fixed scrim behind the open
   menu. Escape-to-close and focus restore live in the shared client script
   (`details[data-menu-control]`); the summary and panel sit above the scrim
   (z-index 50 vs 40) so the toggle stays reachable while the menu is open. */
.public-mobile-menu { position: relative; }

.public-mobile-menu > summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--chrome-menu-bar-gap);
  width: var(--chrome-min-target);
  height: var(--chrome-min-target);
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
  list-style: none;
  cursor: pointer;
}

.public-mobile-menu > summary::-webkit-details-marker { display: none; }

.public-mobile-menu > summary span {
  display: block;
  width: var(--chrome-menu-bar-w);
  height: var(--chrome-menu-bar-h);
  background: var(--color-text);
}

/* scrim behind the open menu (frozen M11-B2 overlay ink); the summary keeps
   its own stacking position above it */
.public-mobile-menu > summary { position: relative; z-index: 50; }

.public-header:has(.public-mobile-menu[open])::after {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--chrome-scrim);
  z-index: 40;
}

.public-mobile-menu-panel {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + var(--chrome-menu-panel-top));
  z-index: 50;
  min-width: var(--chrome-menu-panel-min);
  display: grid;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-overlay);
  padding: var(--chrome-menu-panel-pad);
}

@media (min-width: 768px) {
  .public-nav { display: flex; }
  .public-mobile-menu { display: none; }
}

/* ---------- M14 reference title blocks (ui-016..021 heading treatment) ---------- */

/*
 * Every content surface opens with the same editorial title group: the
 * 3rem x 2px coral signal bar rides the top-left of the breadcrumb (the
 * reference page-intro carries it above the trail), the H1 sets the calmer
 * display scale (Afacad Flux, 700, -.025em, balanced wrap), and the block
 * closes on the hairline rule. Applies to the five surfaces with reference
 * screens (list, detail, blog, article, author); the home hero carries its
 * own copy of the treatment in public.css.
 */
.breadcrumb {
  position: relative;
  margin: var(--chrome-trail-margin);
  padding-block-start: var(--chrome-title-pad-top);
}

.breadcrumb::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: var(--chrome-signal-w);
  height: var(--chrome-signal-h);
  background: var(--color-accent);
}

.list-header,
.blog-header,
.article-header,
.author-identity,
.detail-header {
  padding-block-end: var(--chrome-title-pad-bottom);
  border-block-end: 1px solid var(--color-border);
}

.list-header h1,
.blog-header h1,
.article-header h1,
.author-identity h1,
.detail-header h1 {
  font-family: var(--font-display);
  font-size: var(--chrome-title-size);
  font-weight: var(--weight-bold);
  line-height: 1.05;
  letter-spacing: -0.025em;
  text-wrap: balance;
  max-width: 14ch;
}

/*
 * UI-review unification (P2/P3): the legal documents, the method page and the
 * shared error surfaces (404/503) carry the same title treatment as the five
 * content surfaces — coral signal bar riding the block, chrome title scale —
 * instead of the pre-M14 48px heading, so navigating between surfaces no
 * longer switches title styles. These surfaces have no breadcrumb trail, so
 * the bar anchors to the title block itself; layout-specific spacing stays
 * in each surface's own sheet.
 */
.legal-header,
.method-page-title,
.feedback-title {
  position: relative;
  padding-block-start: var(--chrome-title-pad-top);
}

.legal-header::before,
.method-page-title::before,
.feedback-title::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: var(--chrome-signal-w);
  height: var(--chrome-signal-h);
  background: var(--color-accent);
}

.legal-title,
.method-page-title,
.feedback-title {
  font-family: var(--font-display);
  font-size: var(--chrome-title-size);
  font-weight: var(--weight-bold);
  line-height: 1.05;
  letter-spacing: -0.025em;
  text-wrap: balance;
  max-width: 14ch;
}

/* ---------- footer: frozen M11-B2 paper rail with the 3px coral top rule ---------- */

/* Frozen footer form: one paper-ground rail closed by the single 3px coral
   top rule. The grid row is the wordmark-only brand, the four live legal
   routes and the 資料方法 reference link (PRD-057); the mono bottom row
   carries the honest contact note and the © line. No dark override: the
   canonical tokens remap the ground, ink and focus ring on the dark theme. */
.public-footer {
  margin-block-start: var(--chrome-footer-margin-top);
  border-block-start: 3px solid var(--color-accent);
  padding-block: var(--chrome-footer-pad-block);
  color: var(--color-text-muted);
}

.public-footer-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-6);
}

.public-footer-brand .brand-mark-word {
  font-size: var(--chrome-footer-brand-size);
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
  line-height: 1;
}

/* grid links inherit the muted rail ink; the base .nav-link 44px target and
   its accent-text hover stay from controls.css */
.public-footer .nav-link {
  color: inherit;
  padding-inline: 0;
}

.public-footer .public-footer-method {
  color: var(--color-text);
  font-weight: var(--weight-semibold);
}

/* bottom row: the frozen mono band — contact note left, © line right */
.public-footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-6);
  margin-block-start: var(--chrome-footer-bottom-gap);
  font-family: var(--font-mono);
  font-size: var(--chrome-footer-mono-size);
  line-height: var(--leading-mono);
}

.public-footer-contact {
  margin: 0;
}

.public-footer-copyright {
  margin-inline-start: auto;
}

@media (max-width: 47.99rem) {
  .public-footer-bottom { flex-direction: column; gap: var(--space-1); }
}

/* ---------- UI-021 consent banner (every public route renders it, PRD-048) ---------- */

/* Frozen M11-B2 form: a full-width bar fixed to the viewport bottom, closed
   by the 3px coral top rule with the upward overlay shadow — the first-visit
   banner is visible without scrolling and never depends on page length.
   `[hidden]` is restated because the component display value would otherwise
   override the UA rule. */
.consent-banner[hidden] {
  display: none;
}
.consent-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 30;
  border-block-start: 3px solid var(--color-accent);
  background: var(--color-surface);
  box-shadow: var(--chrome-consent-shadow);
}
.consent-row {
  display: grid;
  gap: var(--space-3);
  padding-block: var(--space-4);
}
/* Keep the banner from covering primary CTAs while it is visible: the client
   script toggles this class. The mobile reserve is ui-021's 15rem (spacing
   tokens) so the compact banner can always be scrolled fully clear. */
body.has-consent-banner {
  padding-bottom: calc(var(--space-16) + var(--space-12) + var(--space-4));
}
@media (min-width: 48rem) {
  .consent-row { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  body.has-consent-banner { padding-bottom: var(--space-16); }
}
.consent-text {
  margin: 0;
  font-size: var(--text-label);
}
.consent-link {
  color: var(--color-accent-text);
}
.consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* M12 (UX-010): at 320x568 the stacked banner rose ~52px past the hero CTA;
   the two actions share one 44px row with one token tighter gaps. */
@media (max-width: 47.99rem) {
  .consent-row { gap: var(--space-2); padding-block: var(--space-3); }
  .consent-actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
