/*
 * GoodLyfe Laser and Wellness: design tokens, "Plum & Pink: Glow" (DESIGN.md explains every token;
 * website-details.md Part 10 records the measurements). Every colour on the public site is defined
 * here and nowhere else (palette test).
 *
 * Doctrine (constitution HC-4, Appendix B E-1):
 * - Brand colour is exactly four tokens: pink and plum measured from the live site, pink-deep and
 *   plum-raised derived from them. The logo file keeps its own colours; it is an image, not a token.
 * - Three tinted neutrals: the cool ground (utility), the blush ground (brand panels) and the page
 *   ground (owner, 2026-09-24). Every other neutral has saturation 0. Shadows have no hue.
 * - White on pink is 4.06:1: a pink fill carries only large bold labels (>= 19 px, 700).
 *   Pink is text only at display size; small pink text is pink-deep (6.21:1 on white).
 */
@font-face {
  font-family: "Brygada 1918 Variable";
  src: url("/fonts/brygada-1918-latin-wght-normal.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Brygada 1918 Variable";
  src: url("/fonts/brygada-1918-latin-wght-italic.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/fonts/poppins-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/fonts/poppins-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("/fonts/poppins-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Rosario Variable";
  src: url("/fonts/rosario-latin-wght-normal.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Rosario Variable";
  src: url("/fonts/rosario-latin-wght-italic.woff2") format("woff2-variations");
  font-weight: 300 700;
  font-style: italic;
  font-display: swap;
}

:root {
  /* Brand: the live site, measured (10.2). */
  --color-pink: #e43292;
  --color-pink-deep: #b8166f;
  --color-plum: #26162f;
  --color-plum-raised: #3a2546;

  /* The tinted neutrals: the live hero ground (utility panels), blush (brand panels), and the page
     ground, a pale pink-white a step lighter than blush so the panels still read (owner, 2026-09-24). */
  --color-cool: #ecf0f4;
  --color-blush: #fdf1f7;
  --color-page: #fff9fc;

  /* Neutrals: saturation 0. */
  --color-white: #ffffff;
  --color-line: #d6d6d6;
  --color-steel: #767676;
  --color-muted: #5c5c5c;
  --color-body: #262626;
  --color-ink: #111111;

  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.06), 0 10px 30px rgb(0 0 0 / 0.1);
  --shadow-lift: 0 2px 4px rgb(0 0 0 / 0.08), 0 18px 44px rgb(0 0 0 / 0.14);
  /* The floating header: soft and wide at the top of the page, a little deeper once scrolled (owner). */
  --shadow-bar: 0 1px 2px rgb(0 0 0 / 0.03), 0 8px 32px rgb(0 0 0 / 0.06);
  --shadow-bar-scrolled: 0 2px 6px rgb(0 0 0 / 0.04), 0 16px 48px rgb(0 0 0 / 0.1);
  /* The scrolled header's frost (owner, 2026-09-24): neutral white at 0.8, so plum reads over anything. */
  --glass-bar: rgb(255 255 255 / 0.8);
  --glass-blur: 12px;
  /* The hatch on frames awaiting a photograph (design preview only). */
  --hatch-line: rgb(0 0 0 / 0.06);

  /* Headings; controls and labels; body (DESIGN.md B.2). */
  --font-heading: "Brygada 1918 Variable", Georgia, "Times New Roman", serif;
  --font-ui: "Poppins", "Segoe UI", system-ui, sans-serif;
  --font-text: "Rosario Variable", "Segoe UI", system-ui, sans-serif;

  --step--1: 0.875rem;
  --step-0: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --step-1: clamp(1.25rem, 1.18rem + 0.36vw, 1.5rem);
  --step-2: clamp(1.5625rem, 1.43rem + 0.63vw, 2rem);
  --step-3: clamp(1.9375rem, 1.6rem + 1.7vw, 3rem);
  --step-4: clamp(2.25rem, 1.18rem + 5.36vw, 4.5rem);

  /* Shape (DESIGN.md B.4): one large circular cut per photograph, inset panels, photo strips, the
     leaf button, one level of cards, chips. */
  --arc: 48%;
  --radius-control: 6px;
  --radius-card: 1.25rem;
  --radius-panel: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  --radius-strip: clamp(1rem, 0.75rem + 1vw, 1.5rem);
  --radius-chip: 999px;
  --radius-leaf: 2rem 2rem 0 2rem;
  /* The header's leaf once the page scrolls: the square corner has moved to the top-left (owner). */
  --radius-leaf-turned: 0 2rem 2rem 2rem;
  /* Every button is a leaf (owner, 2026-09-23): three round corners, the bottom-right one square. */
  --radius-leaf-sm: 1.5rem 1.5rem 0 1.5rem;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: clamp(3.5rem, 2.5rem + 4vw, 6.5rem);

  --container: min(100% - 2rem, 80rem);
  --bar-height: 3.5rem;
  /* The Beam (10.9): the laser line's weight, its dot, and the one easing every move shares. */
  --beam: 3px;
  --beam-dot: 8px;
  --ease-beam: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* The pink label floor: WCAG "large" is 18.66 px bold; 19 px keeps a margin. */
  --label-large: 1.1875rem;
}
/*
 * The public site's base layer: reset, type, and the few patterns shared by many components
 * (container, section, eyebrow, section title). Component styles live in their .astro files.
 * Every colour is a token from tokens.css; none belongs in any other file (palette test).
 */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 6rem; }
/* The desktop header is a two-deck card (its band folds away once scrolled). */
@media (min-width: 1024px) { html { scroll-padding-top: 7.5rem; } }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, picture { display: block; max-width: 100%; height: auto; }
table { border-collapse: collapse; }
address { font-style: normal; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

body {
  background-color: var(--color-page);
  color: var(--color-body);
  font-family: var(--font-text);
  font-size: var(--step-0);
  line-height: 1.55;
  font-variant-numeric: lining-nums;
  padding-bottom: var(--bar-height);
  overflow-x: clip;
}
@media (min-width: 1024px) { body { padding-bottom: 0; } }

a { color: var(--color-pink-deep); text-underline-offset: 0.2em; text-decoration-thickness: 1px; }
a:hover { color: var(--color-plum); }
a, button { touch-action: manipulation; }
:focus-visible { outline: 2px solid var(--color-pink-deep); outline-offset: 2px; }

/* No lone word on a paragraph's last line (headings balance instead, below). */
p, li, dd, blockquote, figcaption { text-wrap: pretty; }

/*
 * Brygada headings (DESIGN.md B.2): weight 500, tight leading, balanced lines. Ink on light
 * grounds; a dark panel sets --heading-ink to white for everything inside it.
 */
.display {
  color: var(--heading-ink, var(--color-ink));
  font-family: var(--font-heading);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: 0;
  text-wrap: balance;
}
h3.display, .display-sm { font-weight: 600; }

/* The one italic: the pink brand words, only at display size (10.3 rule 2, palette test). */
.brand-words { font-style: italic; }

.container { width: var(--container); margin-inline: auto; }

.section { padding: var(--space-8) 0; }
/*
 * Calm panels (DESIGN.md Part H): sections alternate the page ground and a blush band. A band is full width;
 * its content keeps to the container.
 */
.band-blush { background-color: var(--color-blush); }

/*
 * A section with background shapes (ui/Ornaments.astro, DESIGN.md B.8): the shapes run off its edges
 * and are cut there, and its content sits above them. clip, not hidden: a hidden box is a scroll
 * container and would freeze every view() timeline inside it (the reveals, the drift).
 */
.has-ornaments { position: relative; overflow: clip; }
.has-ornaments > :not(.ornaments) { position: relative; z-index: 1; }

/*
 * The marked phrase (H.2): a pink beam under it, at the baseline. Complete by default; where motion
 * is welcome it draws in, on load in the hero and as it scrolls into view elsewhere.
 */
.swash {
  background-image: linear-gradient(var(--color-pink), var(--color-pink));
  background-repeat: no-repeat;
  background-size: 100% 0.14em;
  background-position: left 0 bottom 0.02em;
  padding-bottom: 0.04em;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
@media (prefers-reduced-motion: no-preference) {
  .hero .swash { animation: swash-draw 0.9s var(--ease-beam) 0.35s both; }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .section-head .swash { animation: swash-draw linear both; animation-timeline: view(); animation-range: entry 20% cover 40%; }
  }
}
@keyframes swash-draw { from { background-size: 0 0.14em; } }

/* Small pink text is pink-deep: 6.21:1 on white, 5.42:1 on the cool ground. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* A label that wraps on a phone splits evenly, never leaving one word behind. */
  text-wrap: balance;
  color: var(--color-pink-deep);
}

/*
 * The heading beam (10.9): a pink line ending in a dot. Complete by default; where the browser has
 * scroll-driven animation and motion is welcome, it draws in as the eyebrow enters the screen.
 */
.eyebrow::before {
  content: "";
  flex: none;
  width: 2.75rem;
  height: var(--beam-dot);
  /* A ground where pink would vanish (pink-deep) sets --beam-colour to white. */
  background-image:
    linear-gradient(var(--beam-colour, var(--color-pink)), var(--beam-colour, var(--color-pink))),
    radial-gradient(circle closest-side, var(--beam-colour, var(--color-pink)) 88%, transparent);
  background-repeat: no-repeat;
  background-size: calc(100% - var(--beam-dot)) 2px, var(--beam-dot) var(--beam-dot);
  background-position: left center, right center;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .eyebrow::before {
      animation: beam-draw linear both;
      animation-timeline: view();
      animation-range: entry 20% cover 35%;
    }
  }
}
@keyframes beam-draw {
  from { background-size: 0 2px, var(--beam-dot) var(--beam-dot); background-position: left center, left center; }
}

.section-title { font-size: clamp(2rem, 1.5rem + 2.2vw, 3.25rem); }

.disclosure-note { margin-top: var(--space-6); font-size: 0.9375rem; color: var(--color-muted); max-width: 44rem; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/*
 * Page to page (owner, 2026-09-27: "Confirm as written"): a same-origin navigation cross-fades instead
 * of flashing blank. CSS only,
 * in browsers with cross-document view transitions; others navigate as before. Opacity only (B.6),
 * short, and opted into only where motion is welcome.
 */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
/*
 * 🚨 Never a view-transition-name on the header or any box around it: that makes it a backdrop root, and the
 * frosted bar's blur (.row::before, C.15) would see only the header, so the page shows through it unblurred
 * (owner, 2026-09-28: "why nav dont have blur ?"). tests/design/frosted-header.test.ts guards it.
 */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.26s; animation-timing-function: var(--ease-beam); }

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