/* ==========================================================================
   cocosharon design system
   Layout & rhythm inspired by apple.com (~/design-system-lab/references/apple.md);
   COLOR is the studio brand — black · white · yellow, the same identity as the
   cs mark and the X profile (brand kit: ~/Downloads/cocosharon-brand).

   All pages share this file. Add new pages/components using these tokens —
   never inline hex colors in page files.
   ========================================================================== */

/* ------- Tokens ------- */
:root {
  /* brand — black · white · yellow.
     🔴 Yellow NEVER carries text on a light surface: #FFD23F on #fff is 1.5:1.
     On light it is a SURFACE (button fill on dark tiles, marker stroke behind
     ink, the brand dot); on dark it may be text (13:1 on #111).
     --primary is the BUTTON FILL: black + white text on light, and in dark mode
     it flips to yellow + black text (both ≥ 13:1). Text-weight accent (links,
     kickers, icons, ghost buttons) uses --accent-text: ink on light, yellow on dark. */
  --brand-black: #111111;
  --brand-yellow: #FFD23F;
  --primary: #111111;
  --primary-focus: #2c2c2e;
  --primary-on-dark: #FFD23F;
  --accent-text: #111111;
  --focus-ring: #111111;
  --highlight: #FFD23F;          /* marker stroke behind ink (hero word) */
  --dot: #FFD23F;                /* the brand dot — kicker bullet, badge dot */
  --btn-on-dark: #FFD23F;        /* button fill on dark tiles */
  --btn-on-dark-hover: #FFE07A;
  --on-btn-on-dark: #111111;

  /* surfaces */
  --canvas: #ffffff;
  --parchment: #f5f5f7;
  --pearl: #fafafc;
  --tile-dark: #111111;
  --tile-dark-2: #1c1c1e;
  --black: #000000;
  --hairline: #e0e0e0;
  --divider-soft: #f0f0f0;
  --surface-card: #ffffff;
  --nav-scrim: rgba(250, 249, 245, 0.72);
  --nav-panel: #ffffff;
  --tap-highlight: rgba(255, 210, 63, 0.35);
  --selection: rgba(255, 210, 63, 0.45);
  --fill-soft: rgba(118, 118, 128, 0.12);       /* neutral row/chip fill (mail chooser) */
  --fill-soft-hover: rgba(118, 118, 128, 0.2);

  /* text */
  --ink: #1d1d1f;
  --muted: #6e6e73;
  --on-dark: #ffffff;
  --on-dark-muted: #cccccc;
  --on-primary: #ffffff;
  --body-text: #424245;

  /* type — system-ui resolves to SF Pro on Apple devices; Inter elsewhere */
  --font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", Inter, "Helvetica Neue", sans-serif;
  --font-display: var(--font-body);

  /* shape */
  --r-sm: 8px;
  --r-md: 11px;
  --r-lg: 18px;
  --r-pill: 999px;

  /* the ONE shadow in the system — product renders only */
  --product-shadow: rgba(0, 0, 0, 0.22) 3px 5px 30px 0;

  /* rhythm */
  --nav-h: 56px;
  /* Floored at nav height + 24px on purpose. The nav is sticky, so an anchor
     jump puts a section's top edge underneath it; this padding is what keeps
     the heading clear (measured: heading lands 101px below the nav on desktop,
     53px on mobile). scroll-margin-top is deliberately NOT used — it would push
     the heading a further 57px down rather than reveal anything. This max()
     keeps the guarantee even if the clamp is ever lowered. */
  --section: max(clamp(80px, 10vw, 128px), calc(var(--nav-h) + 24px));
  --wrap-max: 1080px;
  --wrap-pad: clamp(20px, 5vw, 44px);
  /* 노치 아이폰 가로 모드는 Dynamic Island 쪽을 ~59px 잘라내는데 --wrap-pad 의
     천장(44px)은 그 폭에 못 미친다(852px 에서 42.6px = 16px 부족) — 오른쪽 끝
     CTA 가 노치 뒤로 들어간다. env() 는 인셋이 없는 곳에서 0 이라 max() 가
     그 경우를 그대로 no-op 으로 만든다. 좌우를 따로 두는 이유는 인셋이
     한쪽에만 생기기 때문(반대쪽까지 밀면 내용이 가운데에서 어긋난다). */
  --pad-l: max(var(--wrap-pad), env(safe-area-inset-left, 0px));
  --pad-r: max(var(--wrap-pad), env(safe-area-inset-right, 0px));
}

/* ------- Dark mode — tokens only, no component rules -------
   In this design the COLOR CHANGE between tiles IS the divider (no borders,
   no shadows), so a dark palette has to keep every *adjacent* pair distinct.
   Page order: white → parchment → dark → parchment → white → black → parchment.
   That is why --black becomes the LIGHTEST band here: the CTA still lifts off
   the page, and faq(#000) → contact(#232325) stays a visible boundary.
   Verified: 6/6 adjacent boundaries differ, 15/15 text pairs ≥ 4.5:1. */
@media (prefers-color-scheme: dark) {
  :root {
    --primary: #FFD23F;
    --primary-focus: #FFE07A;
    --on-primary: #111111;
    --accent-text: #FFD23F;
    --focus-ring: #FFD23F;

    --canvas: #000000;
    --parchment: #101012;
    --pearl: #08080a;
    --tile-dark: #1c1c1e;
    --tile-dark-2: #26262a;
    --black: #232325;
    --surface-card: #1a1a1c;
    --hairline: #2c2c2e;
    --divider-soft: #1c1c1e;

    --ink: #f5f5f7;
    --muted: #98989d;
    --body-text: #c2c2c7;

    --nav-scrim: rgba(12, 12, 14, 0.72);
    --nav-panel: #1a1a1c;
    --tap-highlight: rgba(255, 210, 63, 0.22);
    --selection: rgba(255, 210, 63, 0.3);
    --fill-soft: rgba(118, 118, 128, 0.24);
    --fill-soft-hover: rgba(118, 118, 128, 0.34);
  }
}

/* ------- Base ------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

/* Tells the UA both themes are supported, so scrollbars and any native control
   follow the active theme instead of staying light. */
:root { color-scheme: light dark; }

body {
  font-family: var(--font-body);
  background: var(--canvas);
  color: var(--ink);
  font-size: 17px;
  line-height: 1.47;
  letter-spacing: -0.022em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

/* Touch: remove the ~300ms double-tap-to-zoom wait on things people tap, and
   set the tap flash to a brand tint rather than leaving the OS grey — or
   removing it, which would leave plain links with no press feedback at all.
   Scoped to interactive elements, so pinch-zoom on the page is unaffected. */
a, button, summary, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: var(--tap-highlight);
}
img { max-width: 100%; display: block; }

::selection { background: var(--selection); }

/* Visible keyboard focus for EVERYTHING, not just .btn. Without this, nav
   links, FAQ rows, footer links and inline links focus invisibly (WCAG 2.4.7).
   .btn keeps its own tighter offset — it is the more specific rule. */
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }

/* Skip to content — first tab stop, parked offscreen until focused */
.skip-link {
  position: absolute; z-index: 200; top: 8px; left: 50%;
  transform: translate(-50%, -160%);
  background: var(--surface-card); color: var(--accent-text);
  border: 1px solid var(--hairline); border-radius: var(--r-pill);
  padding: 11px 20px; font-size: 14px; font-weight: 600; letter-spacing: -0.01em;
  transition: transform .2s cubic-bezier(.25,.7,.3,1);
}
.skip-link:focus { transform: translate(-50%, 0); }

.wrap { max-width: var(--wrap-max); margin: 0 auto; padding-left: var(--pad-l); padding-right: var(--pad-r); }

/* ------- Typography ------- */
.display-hero, .display-lg, .display-md {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
  margin: 0;
}
.display-hero { font-size: clamp(40px, 6vw, 72px); line-height: 1.06; letter-spacing: -0.028em; }
.display-lg { font-size: clamp(32px, 4.2vw, 52px); line-height: 1.08; letter-spacing: -0.024em; }
.display-md { font-size: clamp(24px, 2.8vw, 34px); line-height: 1.2; letter-spacing: -0.02em; }

.kicker { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; color: var(--accent-text); margin: 0 0 14px; }
/* the brand dot in front of every kicker (the yellow dot of the cs mark) */
.kicker::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--dot); margin-right: 8px; vertical-align: middle; transform: translateY(-1px); }
.lead { font-size: clamp(18px, 2vw, 23px); font-weight: 400; line-height: 1.4; letter-spacing: -0.015em; color: var(--muted); max-width: 32em; text-wrap: pretty; margin: 0; }

/* On-dark helpers */
.tile-dark-text .display-hero, .tile-dark-text .display-lg, .tile-dark-text .display-md { color: var(--on-dark); }
.tile-dark-text .lead { color: var(--on-dark-muted); }
.tile-dark-text .kicker { color: var(--primary-on-dark); }

/* ------- Brand mark ------- */
.brand { display: inline-flex; align-items: center; gap: 9px; font-weight: 600; font-size: 16px; letter-spacing: -0.02em; color: var(--ink); }
/* 로고 = 붓글씨 wordmark(웃는 입 밑줄 + 노란 점) — X 프로필·공유 카드와 같다. 밝은 화면은 검정 글씨,
   다크는 흰 글씨를 <picture> 의 prefers-color-scheme 으로 고른다. 원본은 브랜드 키트(build.py). */
.brand picture { display: block; line-height: 0; }
.brand .brand-wm { display: block; height: 34px; width: auto; }
.site-footer .brand .brand-wm { height: 38px; }

/* ------- Buttons (pill = action) ------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-body); font-size: 17px; font-weight: 600; line-height: 1; letter-spacing: -0.015em;
  padding: 13px 24px; border-radius: var(--r-pill); border: 1px solid transparent;
  cursor: pointer; transition: background-color .2s ease, transform .15s ease, border-color .2s ease;
  white-space: nowrap;
}
.btn:active { transform: scale(0.95); }
.btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-focus); }
.btn-ghost { background: transparent; color: var(--accent-text); border-color: var(--accent-text); }
.btn-ghost:hover { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
/* On a dark tile the light-mode accent is ink — invisible there. Dark tiles
   take the yellow instead: yellow text/border for ghost, yellow fill + black
   text for primary (a black button on the black tile would vanish). */
.tile-dark-text .btn-ghost { color: var(--primary-on-dark); border-color: var(--primary-on-dark); }
.tile-dark-text .btn-ghost:hover { background: var(--btn-on-dark); border-color: var(--btn-on-dark); color: var(--on-btn-on-dark); }
.tile-dark-text .btn-primary { background: var(--btn-on-dark); color: var(--on-btn-on-dark); }
.tile-dark-text .btn-primary:hover { background: var(--btn-on-dark-hover); }
.btn-sm { font-size: 14px; padding: 8px 16px; }

/* Apple-style inline link: "Learn more ›" */
.link-arrow { color: var(--accent-text); font-size: 17px; letter-spacing: -0.015em; display: inline-flex; align-items: center; gap: 4px; }
.link-arrow:hover { text-decoration: underline; }
.link-arrow::after { content: "›"; font-size: 1.1em; transform: translateY(-1px); transition: transform .2s ease; }
.link-arrow:hover::after { transform: translateY(-1px) translateX(2px); }
.tile-dark-text .link-arrow { color: var(--primary-on-dark); }

/* ------- Badges ------- */
.badge {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink);
  background: rgba(210, 210, 215, 0.4); border-radius: var(--r-pill); padding: 6px 14px;
}
.tile-dark-text .badge { background: rgba(255, 255, 255, 0.12); color: var(--on-dark); }
.badge .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dot); }

/* ------- Global nav (transparent over hero, frosts white on scroll) ------- */
.site-nav {
  position: sticky; top: 0; z-index: 100;
  background: transparent; border-bottom: 1px solid transparent;
  transition: background .3s ease, border-color .3s ease, -webkit-backdrop-filter .3s ease, backdrop-filter .3s ease;
}
.site-nav.scrolled {
  background: var(--nav-scrim);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: var(--hairline);
}
/* Menu open: bar + panel read as ONE OPAQUE sheet. Must come after .scrolled
   (same specificity) so it wins when both apply. Deliberately not translucent:
   a 300px-tall frosted panel becomes text-over-text anywhere backdrop-filter
   is unavailable or disabled, which is a legibility failure, not a downgrade. */
.site-nav[data-open] {
  background: var(--nav-panel);
  border-bottom-color: var(--hairline);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: var(--nav-h); max-width: var(--wrap-max); margin: 0 auto; padding: 0 var(--pad-r) 0 var(--pad-l); }
.site-nav .brand { color: var(--ink); font-size: 15px; }
.nav-links { display: flex; align-items: center; gap: 32px; }
.nav-links a { font-size: 13px; font-weight: 500; letter-spacing: -0.01em; color: var(--muted); transition: color .18s ease; }
.nav-links a:hover { color: var(--ink); }
.nav-cta { flex: 0 0 auto; }
/* Hamburger — hidden on desktop, 44px touch target on mobile */
.nav-toggle {
  display: none; width: 44px; height: 44px; margin-right: -11px;
  align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--ink);
  border-radius: var(--r-sm); flex: 0 0 auto;
}
.nav-toggle .bars { position: relative; width: 18px; height: 1.5px; border-radius: 2px; background: currentColor; transition: background-color .12s ease; }
.nav-toggle .bars::before, .nav-toggle .bars::after {
  content: ""; position: absolute; left: 0; width: 18px; height: 1.5px; border-radius: 2px; background: currentColor;
  transition: transform .26s cubic-bezier(.25,.7,.3,1);
}
.nav-toggle .bars::before { top: -5.5px; }
.nav-toggle .bars::after { top: 5.5px; }
.site-nav[data-open] .nav-toggle .bars { background-color: transparent; }
.site-nav[data-open] .nav-toggle .bars::before { transform: translateY(5.5px) rotate(45deg); }
.site-nav[data-open] .nav-toggle .bars::after { transform: translateY(-5.5px) rotate(-45deg); }

.nav-links .nav-panel-cta { display: none; color: var(--on-primary); font-weight: 600; } /* .nav-links a(500)가 .btn 굵기를 이긴다 → 다른 버튼과 같이 세미볼드로 고정 */

/* Below 720px the section links used to be display:none — i.e. the site had no
   navigation at all on phones (brand + CTA only). They now live in a panel that
   drops out of the bar. The bar keeps only brand + hamburger because
   brand(101) + CTA(116) + toggle(44) + gaps(48) = 309px overflows a 320px
   viewport; the CTA moves inside the panel instead. */
@media (max-width: 720px) {
  .nav-toggle { display: inline-flex; }
  .nav-cta { display: none; }

  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    display: grid; gap: 0; align-items: stretch;
    padding: 4px var(--pad-r) 18px var(--pad-l);
    background: var(--nav-panel);
    border-bottom: 1px solid var(--hairline);
    visibility: hidden; opacity: 0; transform: translateY(-10px); pointer-events: none;
    transition: opacity .24s ease, transform .24s cubic-bezier(.25,.7,.3,1), visibility .24s;
  }
  .site-nav[data-open] .nav-links { visibility: visible; opacity: 1; transform: none; pointer-events: auto; }
  .nav-links a {
    font-size: 17px; font-weight: 400; color: var(--ink);
    padding: 15px 2px; border-bottom: 1px solid var(--hairline);
  }
  .nav-links a:last-of-type { border-bottom: 0; }
  .nav-links .nav-panel-cta { display: inline-flex; margin-top: 14px; justify-self: start; padding: 13px 24px; border-bottom: 0; }
}

/* ------- Tiles (edge-to-edge, color change = divider) ------- */
.tile { padding-top: var(--section); padding-bottom: var(--section); }
.tile-white { background: var(--canvas); }
.tile-parchment { background: var(--parchment); }
.tile-dark { background: var(--tile-dark); color: var(--on-dark-muted); }
.tile-black { background: var(--black); color: var(--on-dark-muted); }

/* ------- Cards (utility grid, hairline, no shadow) ------- */
.card {
  background: var(--surface-card); border: 1px solid var(--hairline); border-radius: var(--r-lg); padding: 30px 28px;
  transition: transform .35s cubic-bezier(.25,.7,.3,1);
}
.card:hover { transform: scale(1.015); }
.card h3 { font-size: 19px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); margin: 18px 0 8px; }
.card p { margin: 0; font-size: 15px; line-height: 1.5; letter-spacing: -0.01em; color: var(--muted); }
.card .icon { width: 38px; height: 38px; color: var(--accent-text); }

/* ------- Phone mockup (the product render) ------- */
.phone {
  width: clamp(230px, 24vw, 300px); aspect-ratio: 1206 / 2622;
  border-radius: 46px; padding: 10px;
  background: #0b0b0c; border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: var(--product-shadow);
}
.phone img { width: 100%; height: 100%; object-fit: cover; border-radius: 37px; }
/* 홍보 영상은 9:16 이라 폰 화면(1206/2622)보다 넓다 — cover 로 채우면 양옆의 자막이 9%씩 잘린다.
   그래서 영상이 든 폰은 틀 비율을 영상에 맞춘다(높이는 영상 높이 + 여백). */
.phone.phone-video { aspect-ratio: auto; }
.phone video { display: block; width: 100%; height: auto; aspect-ratio: 9 / 16; object-fit: cover; border-radius: 37px; background: #0b0b0c; }

/* ==========================================================================
   Motion library
   ========================================================================== */

/* Scroll reveals — pick a variant per element, stagger with --d */
.reveal { opacity: 0; transition: opacity .9s cubic-bezier(.25,.7,.3,1), transform .9s cubic-bezier(.25,.7,.3,1), filter .9s cubic-bezier(.25,.7,.3,1); transition-delay: var(--d, 0s); }
.reveal.rv-up { transform: translateY(30px); }
.reveal.rv-left { transform: translateX(-36px); }
.reveal.rv-right { transform: translateX(36px); }
.reveal.rv-scale { transform: scale(0.93); }
.reveal.rv-blur { filter: blur(16px); transform: translateY(14px); }
.reveal.in { opacity: 1; transform: none; filter: none; }

/* Key word in the hero. Light: a yellow marker stroke drawn UNDER the ink word
   (yellow can't be the text itself on white — 1.5:1). Dark: the word turns yellow
   (13:1). The stroke draws in once on load; reduced motion shows it already drawn
   (the reduced-motion block below kills the animation, leaving the final size).
   Class name kept as .shimmer so the markup and that block don't change. */
.shimmer {
  background-image: linear-gradient(var(--highlight), var(--highlight));
  background-repeat: no-repeat; background-position: 0 88%; background-size: 100% 0.26em;
  padding: 0 0.04em;
  animation: marker .9s cubic-bezier(.2, 0, 0, 1) .55s both;
}
@keyframes marker { from { background-size: 0% 0.26em; } to { background-size: 100% 0.26em; } }
@media (prefers-color-scheme: dark) {
  .shimmer { background-image: none; color: var(--brand-yellow); animation: none; }
}

/* Idle drift for floating UI chips */
@keyframes floaty { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.float { animation: floaty 5.5s ease-in-out infinite; }
.float-slow { animation: floaty 7.5s ease-in-out 1.4s infinite; }

/* Scroll-scrubbed elements (JS drives transform/opacity via CSS vars) */
.scrub-scale { transform: scale(var(--s, 1)); opacity: var(--o, 1); will-change: transform, opacity; }
.parallax { transform: translateY(var(--py, 0)); will-change: transform; }

/* Statement lines — scroll-linked highlight (Apple copy-reveal) */
.statement-line {
  font-weight: 600; font-size: clamp(34px, 6vw, 76px); line-height: 1.12; letter-spacing: -0.026em;
  color: var(--ink); margin: 0; opacity: var(--p, 0.14); text-wrap: balance;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; filter: none; transition: none; }
  .float, .float-slow, .shimmer { animation: none !important; }
  .statement-line { opacity: 1; }
  .scrub-scale { transform: none; opacity: 1; }
  .parallax { transform: none; }
  .nav-links, .skip-link, .nav-toggle .bars,
  .nav-toggle .bars::before, .nav-toggle .bars::after { transition: none; }
  @media (max-width: 720px) { .nav-links { transform: none; } }
}

/* ------- Mail chooser (assets/mail.js) -------
   Opens on any mailto: link. A plain mailto does nothing on a computer with no
   mail app configured, so the visitor picks Gmail / Outlook (web compose), the
   default mail app, or copies the address. Built by JS — no markup in pages.
   No shadow (the system's one shadow is for product renders); the dimmed
   backdrop + hairline carry the separation. */
.mail-dialog {
  width: min(400px, calc(100% - 32px)); max-width: calc(100% - 24px);
  padding: 26px 24px 24px;
  border: 1px solid var(--hairline); border-radius: 22px;
  background: var(--surface-card); color: var(--ink);
  overscroll-behavior: contain;
}
/* Literal colour on purpose: older engines don't let ::backdrop inherit custom
   properties, and an unresolved var() would leave the page undimmed. */
.mail-dialog::backdrop { background: rgba(0, 0, 0, 0.45); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.mail-dialog[open] { animation: mail-in .32s cubic-bezier(.2, 0, 0, 1); }
.mail-dialog[open]::backdrop { animation: mail-fade .25s ease-out; }
@keyframes mail-in { from { opacity: 0; transform: translateY(12px) scale(.98); } }
@keyframes mail-up { from { opacity: 0; transform: translateY(28px); } }
@keyframes mail-fade { from { opacity: 0; } }

.mail-dialog h2 { margin: 0 44px 4px 0; font-size: 21px; font-weight: 600; line-height: 1.25; letter-spacing: -0.02em; }
.mail-dialog-addr { margin: 0 0 20px; font-size: 15px; letter-spacing: -0.01em; color: var(--body-text); overflow-wrap: anywhere; user-select: all; -webkit-user-select: all; }

/* Close: 44px hit area, 32px visible circle */
.mail-dialog-x {
  position: absolute; top: 12px; right: 12px; width: 44px; height: 44px;
  display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--muted); cursor: pointer;
}
.mail-dialog-x::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--fill-soft); transition: background-color .15s ease; }
.mail-dialog-x:hover::before { background: var(--fill-soft-hover); }
.mail-dialog-x svg { position: relative; width: 16px; height: 16px; }

.mail-dialog-opts { display: grid; gap: 8px; }
.mail-dialog-opts > * {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; min-height: 54px; padding: 0 16px 0 18px;
  border: 0; border-radius: 14px; background: var(--fill-soft); color: var(--ink);
  font: 600 17px/1.2 var(--font-body); letter-spacing: -0.015em; text-align: left;
  cursor: pointer; transition: background-color .15s ease, transform .15s ease;
}
.mail-dialog-opts > *:hover { background: var(--fill-soft-hover); }
.mail-dialog-opts > *:active { transform: scale(.98); }
.mail-dialog-opts svg { flex: none; color: var(--muted); }
.mail-dialog-opts [data-copy-icon] { display: grid; }
.mail-dialog-opts .is-done svg { color: var(--ink); }
.mail-dialog-sr { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Phones: a bottom sheet, within thumb reach */
@media (max-width: 560px) {
  .mail-dialog { width: calc(100% - 24px); margin: auto auto max(12px, env(safe-area-inset-bottom)); border-radius: 26px; padding: 24px 20px 20px; }
  .mail-dialog[open] { animation-name: mail-up; }
}
/* Must sit AFTER the rules above: a media query adds no specificity, so the
   global reduced-motion block (which comes earlier in this file) would lose. */
@media (prefers-reduced-motion: reduce) {
  .mail-dialog[open], .mail-dialog[open]::backdrop { animation: none; }
  .mail-dialog-opts > *, .mail-dialog-x::before { transition: none; }
  .mail-dialog-opts > *:active { transform: none; }
}

/* ------- Footer (parchment, dense links) ------- */
.site-footer { background: var(--parchment); color: var(--muted); border-top: 1px solid var(--hairline); }
.site-footer .foot-inner { display: flex; flex-wrap: wrap; gap: 32px 56px; justify-content: space-between; padding-top: 48px; padding-bottom: 40px; font-size: 14px; letter-spacing: -0.01em; }
.site-footer .brand { color: var(--ink); }
.site-footer .col { display: grid; gap: 2px; align-content: start; }
.site-footer .col-title { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.site-footer .col a { line-height: 2.1; color: var(--muted); transition: color .18s ease; }
.site-footer .col a:hover { color: var(--ink); }
.site-footer .legal-row { border-top: 1px solid var(--hairline); padding-top: 18px; padding-bottom: 24px; display: flex; flex-wrap: wrap; gap: 6px 24px; justify-content: space-between; font-size: 12px; color: var(--muted); }
.site-footer .legal-row a:hover { color: var(--ink); }

/* ==========================================================================
   Legal pages (privacy.html / terms.html)
   ========================================================================== */
.legal-header { background: var(--canvas); border-bottom: 1px solid var(--divider-soft); }
.legal-nav { display: flex; align-items: center; justify-content: space-between; height: 56px; }
.legal-nav .back { font-size: 14px; color: var(--accent-text); }
.legal-nav .back:hover { text-decoration: underline; }

.legal-main { max-width: 720px; margin: 0 auto; padding: 64px var(--pad-r) 96px var(--pad-l); }
.legal-main h1 { font-weight: 600; font-size: clamp(34px, 5vw, 48px); letter-spacing: -0.028em; line-height: 1.07; color: var(--ink); margin: 0 0 10px; }
.legal-main .eff { color: var(--muted); font-size: 14px; margin: 0 0 44px; }
.legal-main h2 { font-weight: 600; font-size: 22px; letter-spacing: -0.02em; color: var(--ink); margin: 44px 0 10px; }
.legal-main p, .legal-main li { font-size: 16px; line-height: 1.6; letter-spacing: -0.011em; color: var(--body-text); text-wrap: pretty; }
.legal-main ul { padding-left: 20px; }
.legal-main li { margin: 7px 0; }
.legal-main strong { color: var(--ink); font-weight: 600; }
/* In light mode the accent is ink, so a link would look like body text —
   the underline is what marks it (WCAG 1.4.1: not color alone). */
.legal-main a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.legal-main a:hover { text-decoration-thickness: 2px; }
.legal-main .meta { color: var(--muted); font-size: 14px; margin-top: 26px; }
/* Monospace renders visually larger at the same px, so step it down to sit on
   the same line as the surrounding prose. */
.legal-main code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.92em; }

.legal-footer { background: var(--parchment); border-top: 1px solid var(--hairline); }
.legal-footer .foot { padding-top: 24px; padding-bottom: 48px; color: var(--muted); font-size: 12px; }
.legal-footer a:hover { color: var(--ink); }
