/* ============================================================================
   Responsive layer for the STSA member-app site.

   SOURCE OF TRUTH — `tools/unpack-export.mjs` copies this to
   site/assets/responsive.css and links it last in <head>. Never edit the copy
   under site/; the generator deletes that directory and rebuilds it.

   Why !important: the design export writes all styling as inline style=""
   attributes, and an inline declaration outranks any stylesheet rule on
   specificity. An author !important declaration outranks it back. The pages
   contain no classes, no ids, and no !important of their own, so there is no
   cascade to fight here — only the inline attributes.

   Selectors hang off two hooks the generator stamps: [data-r="hero"] on the
   landing page's <main>, [data-r="doc"] on the policy page's <main>. That
   keeps each rule scoped to one page without a per-page stylesheet, and
   assertLayoutContract() in the generator fails the build if a re-export
   moves the markup out from under these selectors.

   The exported design is desktop-only and assumes its 1180px preview width.
   Below that it does not merely look cramped: <main> is a `1fr 1fr` grid whose
   items default to min-width:auto, so neither column can shrink below its
   content and the page overflows horizontally from 1024px down.
   ========================================================================= */

/* The English gloss that sat between each policy heading and its body is
   dropped by the generator, leaving the heading's 4px bottom margin — tuned
   for having something under it — too tight against the body text. */
[data-r="doc"] section h2 { margin-bottom: 9px !important; }

/* Page gutter, narrowing with the viewport. max() with the safe-area inset
   keeps content clear of the notch in landscape; the inset resolves to 0
   everywhere else. */
:root {
  --gx: 32px;
  --gl: max(var(--gx), env(safe-area-inset-left, 0px));
  --gr: max(var(--gx), env(safe-area-inset-right, 0px));
}

/* clip, not hidden: `hidden` would make the root a scroll container and break
   the sticky header. Belt-and-braces — the rules below remove the causes. */
html { overflow-x: clip; }

/* svh rather than vh, so the first paint is not sized to a viewport that the
   mobile browser's collapsing toolbar immediately invalidates. */
body > div { min-height: 100svh !important; }

/* Reserve the screenshots' box before they decode. Both PNGs are 1206x2622;
   the generator asserts that, since a differently proportioned re-export
   would stretch them. Declared in CSS rather than as width/height attributes
   because attributes are presentational hints that lose to author CSS — if
   this stylesheet ever failed to load, the phones would render 2622px tall. */
[data-r="hero"] img { aspect-ratio: 1206 / 2622; height: auto; }


/* 1119px — one below the design's own max-width:1120px, so at 1120px and up
   the page renders exactly as exported. The two columns stay side by side;
   this tier only makes them able to shrink. */
@media (max-width: 1119px) {
  [data-r="hero"] {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important;
    gap: 44px !important;
    padding: 72px var(--gr) 64px var(--gl) !important;
  }
  /* THE overflow fix. A replaced element's automatic minimum size is its
     specified width, so the 258px/232px screenshots refuse to shrink and
     push the row wide. Flex ratios do nothing here; min-width:0 does. */
  [data-r="hero"] img { min-width: 0 !important; }
  [data-r="hero"] h1 {
    font-size: 54px !important; line-height: 1.08 !important;
    letter-spacing: -.022em !important;
  }
  [data-r="hero"] > div:last-child { min-height: 600px !important; gap: 20px !important; }
  /* The decorative glow is position:absolute with no offsets, so it sits at
     its static position and hangs off the right edge. Anchor and bound it. */
  [data-r="hero"] > div:last-child > div {
    left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: min(100%, 480px) !important; height: auto !important;
    aspect-ratio: 1; border-radius: 50% !important;
  }
}

/* Small laptops and landscape tablets. */
@media (max-width: 1023px) {
  :root { --gx: 24px; }
  [data-r="hero"] { padding: 64px var(--gr) 56px var(--gl) !important; gap: 36px !important; }
  [data-r="hero"] h1 {
    font-size: 48px !important; line-height: 1.10 !important;
    letter-spacing: -.020em !important; margin: 0 0 18px !important;
  }
  [data-r="hero"] > div:first-child > p {
    font-size: 17px !important; line-height: 1.6 !important; margin: 0 0 30px !important;
  }
  [data-r="hero"] > div:last-child { min-height: 540px !important; gap: 18px !important; }
  [data-r="hero"] > div:last-child > div { width: min(100%, 420px) !important; }
  [data-r="hero"] img:first-of-type { width: 212px !important; border-radius: 26px !important; }
  [data-r="hero"] img:last-of-type  { width: 190px !important; border-radius: 24px !important; }
  header > div { padding: 18px var(--gr) 18px var(--gl) !important; }
  footer > div { padding-left: var(--gl) !important; padding-right: var(--gr) !important; }
  [data-r="doc"] { padding-left: var(--gl) !important; padding-right: var(--gr) !important; }
}

/* 899px — the structural flip. The hero stacks to one centred column, and the
   screenshots get BIGGER rather than smaller: the layout just freed up the
   full width, and a hero whose product shrinks when given more room reads as
   a bug. */
@media (max-width: 899px) {
  [data-r="hero"] {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 48px !important; max-width: 720px !important;
    padding: 56px var(--gr) 64px var(--gl) !important;
    text-align: center; align-content: start;
  }
  /* CJK typography: leading and tracking move OPPOSITE to size. The export's
     1.04/-1.4px is tuned for a 62px headline; carried down unchanged it would
     jam full-width Han glyphs together. Tracking is restated in em so it
     tracks the size. text-wrap:balance becomes pretty — Chrome's balancer
     will break between any two Han characters, since CJK has no word
     boundaries to respect. */
  [data-r="hero"] h1 {
    font-size: 46px !important; line-height: 1.14 !important;
    letter-spacing: -.018em !important; margin: 0 0 16px !important;
    text-wrap: pretty !important;
  }
  [data-r="hero"] > div:first-child > p {
    max-width: 26em !important; margin: 0 auto 28px !important;
    color: rgba(60, 60, 67, .76) !important;   /* .70 was 4.25:1 — under AA */
  }
  [data-r="hero"] > div:first-child > div:first-of-type { justify-content: center; }
  [data-r="hero"] > div:first-child > div:last-of-type { color: rgba(60, 60, 67, .78) !important; }
  [data-r="hero"] > div:last-child { min-height: 0 !important; gap: 16px !important; }
  [data-r="hero"] > div:last-child > div { width: min(100%, 460px) !important; }
  [data-r="hero"] img:first-of-type {
    width: 240px !important; border-radius: 30px !important;
    box-shadow: 0 20px 44px rgba(28, 28, 30, .18) !important;
  }
  [data-r="hero"] img:last-of-type {
    width: 216px !important; border-radius: 27px !important;
    box-shadow: 0 14px 32px rgba(28, 28, 30, .13) !important;
  }
  header > div { padding: 14px var(--gr) 14px var(--gl) !important; gap: 12px !important; }
  /* The lockup is ~7:1, so its width is what constrains the header row, not
     its height. Shrink it in step with the gutters so it and the nav link
     keep sharing one line. */
  header img { height: 30px !important; }
  /* Grows the header link's hit area to 44px without growing the sticky bar. */
  header a { position: relative; }
  header a::after { content: ""; position: absolute; inset: -12px -8px; }
  /* 36px social chips are under the 44px minimum; 13px radius holds the
     squircle proportion the design uses at 36px/10px. */
  footer > div:first-child > div:last-child { gap: 10px !important; }
  footer > div:first-child > div:last-child > a {
    width: 44px !important; height: 44px !important; border-radius: 13px !important;
  }
  footer > div:first-child > div:last-child > a > svg { width: 20px; height: 20px; }
  /* Footer legal links render as ~26x19 text. inline-flex with a minimum box
     is used rather than padding so the target is the element itself — a
     padded inline box still reports its text height to anything measuring it,
     and 首頁 is only 26px wide, so height alone would not be enough. */
  footer > div > a {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; min-width: 44px;
  }
  footer > div:last-child { color: rgba(60, 60, 67, .78) !important; }
  [data-r="doc"] { padding-top: 48px !important; padding-bottom: 56px !important; }
  [data-r="doc"] > h1 {
    font-size: 34px !important; line-height: 1.2 !important; letter-spacing: -.020em !important;
  }
  [data-r="doc"] > p:first-of-type { color: rgba(60, 60, 67, .78) !important; }
}

/* Large phones / portrait tablets. */
@media (max-width: 767px) {
  [data-r="hero"] { padding: 48px var(--gr) 56px var(--gl) !important; gap: 40px !important; }
  [data-r="hero"] h1 {
    font-size: 42px !important; line-height: 1.16 !important; letter-spacing: -.015em !important;
  }
  [data-r="hero"] > div:first-child > p { margin: 0 auto 26px !important; }
  [data-r="hero"] > div:last-child { gap: 14px !important; }
  [data-r="hero"] > div:last-child > div { width: min(100%, 420px) !important; }
  [data-r="hero"] img:first-of-type { width: 228px !important; border-radius: 28px !important; }
  [data-r="hero"] img:last-of-type  { width: 206px !important; border-radius: 26px !important; }
}

/* 599px — phones. Two phones side by side at a readable size no longer fit, so
   they overlap into a fan: front phone raised and forward, rear one tucked
   behind and dropped. Offsetting on both axes reads as depth rather than as a
   collision. To revert to side-by-side, delete the negative margins and
   restore a positive gap. The corner radii track the widths because the
   radius masks a bezel drawn inside the PNG — a fixed radius would show a
   sliver of square corner once the image scales. */
@media (max-width: 599px) {
  [data-r="hero"] { padding: 40px var(--gr) 48px var(--gl) !important; gap: 36px !important; }
  [data-r="hero"] h1 {
    font-size: 38px !important; line-height: 1.18 !important;
    letter-spacing: -.012em !important; margin: 0 0 14px !important;
  }
  [data-r="hero"] > div:first-child > p { max-width: 100% !important; margin: 0 auto 26px !important; }
  [data-r="hero"] > div:last-child { gap: 0 !important; align-items: flex-end !important; }
  [data-r="hero"] img:first-of-type {
    width: clamp(160px, 56%, 236px) !important;
    border-radius: clamp(19px, 6.2vw, 30px) !important;
    box-shadow: 0 16px 34px rgba(28, 28, 30, .18) !important; z-index: 2;
  }
  [data-r="hero"] img:last-of-type {
    width: clamp(142px, 50%, 212px) !important;
    border-radius: clamp(18px, 5.8vw, 28px) !important;
    box-shadow: 0 10px 24px rgba(28, 28, 30, .12) !important;
    margin-left: clamp(-84px, -18%, -46px);
    margin-bottom: clamp(14px, 5%, 24px); z-index: 1;
  }
  /* Bounded, not deleted: without the glow the mobile hero is greyscale from
     the headline to the footer. Not clipped either — clipping would amputate
     the phones' drop shadows. */
  [data-r="hero"] > div:last-child > div {
    width: min(100%, 360px) !important; top: 44%;
    background: radial-gradient(circle, rgba(198, 133, 120, .13), rgba(198, 133, 120, 0) 70%) !important;
  }
  footer > div {
    flex-direction: column; align-items: center !important;
    text-align: center; gap: 16px !important;
  }
  footer > div > div:empty { display: none; }   /* the flex:1 spacers */
  [data-r="doc"] { padding-top: 36px !important; padding-bottom: 44px !important; }
  [data-r="doc"] > h1 { font-size: 30px !important; line-height: 1.22 !important; }
  [data-r="doc"] > p:nth-of-type(2) {
    font-size: 16px !important; line-height: 1.65 !important; padding: 18px !important;
  }
  [data-r="doc"] section { padding: 18px !important; margin-bottom: 10px !important; }
  [data-r="doc"] > div:last-child { padding: 18px !important; }
  [data-r="doc"] h2 { font-size: 18px !important; line-height: 1.3 !important; }
  [data-r="doc"] section p { line-height: 1.7 !important; }
}

/* 479px — the common phone width. Store badges stack; capped at 320px rather
   than full-bleed so they stay button-shaped. */
@media (max-width: 479px) {
  :root { --gx: 20px; }
  [data-r="hero"] { padding: 36px var(--gr) 44px var(--gl) !important; gap: 32px !important; }
  [data-r="hero"] h1 {
    font-size: 36px !important; line-height: 1.2 !important; letter-spacing: -.010em !important;
  }
  [data-r="hero"] > div:first-child > p { margin: 0 auto 24px !important; }
  [data-r="hero"] > div:first-child > div:first-of-type {
    flex-direction: column; align-items: center; gap: 10px !important;
  }
  [data-r="hero"] > div:first-child > div:first-of-type > a {
    width: min(100%, 320px); justify-content: center;
  }
  header > div { padding: 11px var(--gr) 11px var(--gl) !important; gap: 10px !important; }
  header img { height: 26px !important; }
}

/* 374px — iPhone SE. The header must still fit logo + wordmark + link on one
   line; the headline's 6 full-width glyphs are 192px at 32px. */
@media (max-width: 374px) {
  :root { --gx: 16px; }
  [data-r="hero"] { padding: 32px var(--gr) 40px var(--gl) !important; gap: 28px !important; }
  [data-r="hero"] h1 { font-size: 32px !important; letter-spacing: -.008em !important; }
  [data-r="hero"] img:first-of-type { width: clamp(150px, 60%, 200px) !important; }
  [data-r="hero"] img:last-of-type {
    width: clamp(134px, 53%, 180px) !important;
    margin-left: clamp(-64px, -20%, -40px);
  }
  header img { height: 23px !important; }
  header a { font-size: 14px !important; }
  [data-r="doc"] > h1 { font-size: 28px !important; }
}

/* Landscape phone: the width ladder alone would hand a 390px-tall viewport
   500px of hero. Unfan here — at this size the overlap buys nothing. */
@media (max-width: 899px) and (max-height: 520px) and (orientation: landscape) {
  [data-r="hero"] {
    padding-top: 40px !important; padding-bottom: 48px !important; gap: 32px !important;
  }
  [data-r="hero"] h1 { font-size: 40px !important; line-height: 1.16 !important; }
  [data-r="hero"] > div:last-child { gap: 16px !important; align-items: center !important; }
  [data-r="hero"] img:first-of-type { width: 200px !important; border-radius: 25px !important; }
  [data-r="hero"] img:last-of-type {
    width: 180px !important; border-radius: 23px !important;
    margin-left: 0; margin-bottom: 0;
  }
}

/* Touch targets are a property of the input device, not the viewport. The
   width ladder above stops at 899px, which would leave a landscape iPad — a
   touch device at 1024px — with 36px chips. Keyed on pointer instead, so this
   reaches every touch device and never alters the mouse-driven desktop
   rendering the design was signed off at. */
@media (pointer: coarse) {
  footer > div:first-child > div:last-child > a {
    width: 44px !important; height: 44px !important; border-radius: 13px !important;
  }
  footer > div:first-child > div:last-child > a > svg { width: 20px; height: 20px; }
  footer > div > a {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; min-width: 44px;
  }
  header a { position: relative; }
  header a::after { content: ""; position: absolute; inset: -12px -8px; }
}

/* Gives the tap the physical feedback an iOS-styled page implies. */
@media (prefers-reduced-motion: no-preference) {
  [data-r="hero"] > div:first-child > div:first-of-type > a { transition: transform .18s ease; }
  [data-r="hero"] > div:first-child > div:first-of-type > a:active { transform: scale(.97); }
}
