/* =========================================================================
   base.css — Delvia design system.

   The brief this answers: salon and clinic owners deciding on a 15.000–90.000 €
   machine. The page has to feel clinical, precise and expensive. Three rules
   carry that, and everything below is downstream of them:

   1. The machines are the design. They are white and chrome, photographed on
      dark grounds. So the page gets out of the way: near-black, generous air,
      hairlines instead of boxes. A bordered card around every object makes a
      catalogue look like a dashboard.
   2. One accent, used only where something is interactive or genuinely
      exceptional. Prices are NOT accent-coloured — a price is information, and
      colouring it competes with the button you actually want pressed.
   3. Motion is slow and weighty. Nothing bounces, nothing springs.
   ========================================================================= */

@import url('./fonts.css');

:root {
  /* Ground. Cooler and deeper than a neutral grey — reads as clinical. */
  --bg:        #07090D;
  --bg-lift:   #0B0E14;   /* alternating section ground */
  --plate:     #10141C;   /* the surface product photography sits on */
  --plate-2:   #161B25;

  /* Ink */
  --text:      #F3F5F8;
  --dim:       #A0A9B8;   /* secondary copy */
  --faint:     #5D6675;   /* labels, meta */

  /* One accent. */
  --accent:    #4FD8E8;
  --accent-dk: #1D9FB4;
  --accent-ink:#04161A;

  /* Hairlines, not borders. */
  --rule:      #1B212C;
  --rule-lit:  #2A3342;

  --danger:    #FF6B84;
  --ok:        #4FE0A8;

  --font-display: 'Sora', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'Sora', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, monospace;

  --ease:      cubic-bezier(0.22, 1, 0.36, 1);   /* slow out, no overshoot */
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);

  --container: 1440px;
  --gutter: clamp(20px, 4vw, 56px);
  --r: 4px;          /* almost square. Big radii read as consumer software. */
  --r-lg: 8px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Something has to stop the marquee and the parallax bands from widening the
     page. `hidden` does that but silently turns the body into a scroll
     container, which kills every `position: sticky` on the site — the chapter
     index on the content pages simply never sticks. `clip` clips without
     creating that scroll container. */
  overflow-x: hidden;
}
@supports (overflow: clip) {
  body { overflow-x: clip; }
}
img, picture, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
p { margin: 0 0 1.1em; }
ul, ol { margin: 0 0 1.1em; padding-left: 1.15em; }
hr { border: 0; border-top: 1px solid var(--rule); margin: 0; }
table { border-collapse: collapse; width: 100%; }
::selection { background: var(--accent); color: var(--accent-ink); }

/* ---------- Typography ----------
   Display sizes are large and tightly tracked; body stays comfortable. The
   contrast between the two is what makes a page feel designed rather than
   scaled. Figures are tabular everywhere a number matters, so prices and specs
   align in a column instead of shimmering. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.035em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.4rem, 5.6vw, 4.6rem); }
h2 { font-size: clamp(1.9rem, 3.9vw, 3.1rem); }
h3 { font-size: clamp(1.1rem, 1.7vw, 1.35rem); letter-spacing: -0.02em; line-height: 1.25; }
h4 { font-size: 1rem; letter-spacing: -0.01em; }

.lead {
  font-size: clamp(1.05rem, 1.35vw, 1.28rem);
  line-height: 1.6; color: var(--dim); max-width: 58ch; font-weight: 400;
}
.dim, .muted { color: var(--dim); }
.accent { color: var(--accent); }

/* Section label. The rule-and-number pairing is what gives a catalogue its
   sense of order, and it costs nothing. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: .7rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: .2em;
  color: var(--faint);
  display: flex; align-items: center; gap: .85rem;
  margin: 0 0 1.4rem;
}
.eyebrow::before {
  content: ""; width: 28px; height: 1px; background: var(--accent); flex: none;
}

.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---------- Prose ---------- */
.prose { max-width: 68ch; }
.prose > :first-child { margin-top: 0; }
.prose h2 { margin-top: 2em; font-size: clamp(1.45rem, 2.4vw, 2rem); }
.prose h3 { margin-top: 1.9em; font-size: clamp(1.1rem, 1.6vw, 1.3rem); }
.prose p, .prose li { color: var(--dim); }
.prose strong, .prose b { color: var(--text); font-weight: 600; }
.prose a { color: var(--text); box-shadow: inset 0 -1px 0 var(--accent-dk); transition: box-shadow .25s var(--ease); }
.prose a:hover { box-shadow: inset 0 -2px 0 var(--accent); }
.prose li { margin-bottom: .35em; }
.prose li::marker { color: var(--accent-dk); }
.prose blockquote {
  margin: 2.4rem 0; padding: 0 0 0 1.6rem;
  border-left: 1px solid var(--accent);
  color: var(--text); font-size: 1.06rem;
}
.prose blockquote > :last-child { margin-bottom: 0; }
.prose img { border-radius: var(--r-lg); margin: 2.2rem 0; }
.prose figure { margin: 2.2rem 0; }

/* ---------- Layout ---------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container--narrow { max-width: 760px; }

/* Rhythm alternates deliberately: not every section gets the same air. */
.section { padding-block: clamp(60px, 6.5vw, 108px); position: relative; }
.section--tight { padding-block: clamp(40px, 4.5vw, 72px); }
.section--lift { background: var(--bg-lift); }
.section--ruled { border-top: 1px solid var(--rule); }
.section--center { text-align: center; }
.section__head { max-width: 64ch; margin-bottom: clamp(36px, 4.5vw, 72px); }
.section--center .section__head { margin-inline: auto; }
.section__head .lead { margin-bottom: 0; }
.section__head + .section__actions { margin-bottom: 2rem; }

/* A head that puts the title left and the "see all" link right reads as an
   index, which is what a catalogue section is. */
.head-row {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem;
  margin-bottom: clamp(28px, 3.5vw, 56px); flex-wrap: wrap;
}
.head-row .section__head { margin-bottom: 0; }

.grid { display: grid; gap: clamp(18px, 2vw, 30px); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 6vw, 88px); align-items: center; }

/* ---------- Accessibility ---------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 1000;
  background: var(--accent); color: var(--accent-ink); padding: .75rem 1.2rem; font-weight: 600;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- Buttons ----------
   The accent button is the only filled element on the page. Everything else is
   a hairline or plain text, so the eye always knows where the action is. */
.btn {
  --btn-pad: .95rem 1.7rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  padding: var(--btn-pad); border-radius: 999px; border: 1px solid transparent;
  font-family: var(--font-display); font-size: .9rem; font-weight: 600; line-height: 1;
  letter-spacing: -0.01em; cursor: pointer; text-align: center; position: relative;
  /* Every variant below sets its own fill, so the base has to clear the one a
     <button> element brings with it. Without this the outline and quiet
     variants rendered as light grey pills with grey text on a black page, which
     reads as a disabled control rather than a button. */
  background: transparent;
  /* A CTA label that wraps to two lines is a broken button. Labels here are all
     one or two words, so they never need to wrap. */
  white-space: nowrap;
  transition: background-color .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), transform .3s var(--ease);
}
.btn--accent { background: var(--accent); color: var(--accent-ink); }
.btn--outline { border-color: var(--rule-lit); color: var(--text); }
.btn--ghost { color: var(--text); background: var(--plate-2); }
/* For a button that repeats down a listing: present, reachable, and not
   competing with itself twenty times over. It fills only under the cursor, so
   the label carries full contrast rather than the muted grey of body copy. */
.btn--quiet { border-color: var(--rule-lit); color: var(--text); }
.btn--sm { --btn-pad: .68rem 1.25rem; font-size: .84rem; }
.btn--block { width: 100%; }

/* Text link with a rule that draws itself on hover. */
.btn--text {
  padding: 0; border: 0; background: none; color: var(--text);
  border-radius: 0; gap: .5rem; align-self: flex-start;
}
.btn--text::after {
  content: "→"; color: var(--accent);
  transition: transform .4s var(--ease);
}
.link-line { position: relative; padding-bottom: 2px; }
.link-line::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: var(--rule-lit); transform-origin: right; transition: transform .4s var(--ease);
}
.link-line::before {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform .4s var(--ease); z-index: 1;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
.site-header.is-stuck {
  border-bottom-color: var(--rule);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
}
.site-header__inner { display: flex; align-items: center; gap: clamp(1rem, 3vw, 3rem); min-height: 76px; }
.site-header__brand { display: flex; align-items: center; margin-right: auto; }
.site-header__brand img { height: 30px; width: auto; }
/* The wordmark is 4:1, so height alone sizes it and the width follows. */
.site-header__logo { height: 30px; width: auto; }
.site-footer__logo { height: 34px; width: auto; margin-bottom: 1rem; }
.site-header__cta { display: inline-flex; gap: .7rem; align-items: center; }
.site-header__phone { font-family: var(--font-mono); font-size: .82rem; color: var(--dim); letter-spacing: .02em; }
.site-header__phone:hover { color: var(--text); }

.site-nav__menu { list-style: none; display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.1rem); margin: 0; padding: 0; }
.site-nav__menu > li { position: relative; }
.site-nav__menu > li > a {
  font-size: .89rem; font-weight: 500; letter-spacing: -0.005em;
  color: var(--dim); padding-block: 1.6rem; display: inline-block; position: relative;
  transition: color .3s var(--ease);
}
.site-nav__menu > li > a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 1.15rem; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
.site-nav__menu > li > a:hover { color: var(--text); }
.site-nav__menu .current-menu-item > a { color: var(--text); }
.site-nav__menu .current-menu-item > a::after { transform: scaleX(1); }

.site-nav__menu .sub-menu {
  position: absolute; top: 100%; left: -1.1rem; min-width: 250px; list-style: none;
  margin: 0; padding: .45rem; background: var(--plate); border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
}
.site-nav__menu .sub-menu a {
  display: block; padding: .55rem .8rem; border-radius: var(--r); font-size: .88rem;
  color: var(--dim); transition: background-color .2s, color .2s;
}
.site-nav__menu .sub-menu a:hover { background: var(--plate-2); color: var(--text); }
.site-nav__menu li:hover > .sub-menu,
.site-nav__menu li:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: none; }

.site-nav__toggle { display: none; background: none; border: 0; padding: .5rem; cursor: pointer; flex-direction: column; gap: 5px; }
.site-nav__toggle span { width: 20px; height: 1.5px; background: var(--text); display: block; transition: transform .35s var(--ease), opacity .25s; }
.site-nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.site-nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.site-nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.mobile-cta {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  padding: .65rem var(--gutter) calc(.65rem + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 95%, transparent);
  backdrop-filter: blur(12px); border-top: 1px solid var(--rule); gap: .55rem;
}
.mobile-cta .btn { flex: 1; }

/* ---------- Product card ----------
   No border, no box. The photograph gets a plate of its own that is lighter
   than the page, so a white machine has something to sit on; the type sits
   directly on the page beneath it. That separation is the whole trick. */
.card { display: flex; flex-direction: column; height: 100%; position: relative; }
.card__media {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  background: linear-gradient(180deg, #FFFFFF 0%, #F1F3F6 100%);
  border-radius: var(--r-lg);
}
.card__media img {
  width: 100%; height: 100%; object-fit: contain; padding: 9% 9% 11%;
  transition: transform .8s var(--ease);
}
.card__media::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--r-lg);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.07);
  pointer-events: none;
}
.card__body { padding: 1.15rem .1rem 0; display: flex; flex-direction: column; gap: .3rem; flex: 1; }
.card__title { font-size: 1rem; font-weight: 500; line-height: 1.35; letter-spacing: -0.015em; margin: 0; }
.card__title a { transition: color .25s var(--ease); }
.card__meta { font-family: var(--font-mono); font-size: .74rem; color: var(--faint); letter-spacing: .04em; }
/* A price is information, not a call to action — it stays in the text colour. */
.card__price { font-size: .95rem; font-weight: 500; color: var(--text); margin: 0; font-variant-numeric: tabular-nums; }
.card__actions { margin-top: auto; padding-top: .9rem; display: flex; gap: .5rem; align-items: center; }
.card__badge {
  position: absolute; top: .85rem; left: .85rem; z-index: 2;
  background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-mono); font-size: .64rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em; padding: .3rem .55rem; border-radius: var(--r);
}
/* The whole card is the link; the buttons sit above it. */
.card__link { position: absolute; inset: 0; z-index: 1; }
.card__actions .btn, .card__actions button { position: relative; z-index: 2; }

/* ---------- Article card ----------
   A shared component: the blog listing and the homepage both show these.

   It has to be its own thing rather than a variant of .card, because .card is
   built for product photography — a white plate with the object contained
   inside it and generous padding. Feed an article cover into that and you get a
   large white box with a small picture floating in the middle of it, which is
   exactly what the homepage was doing: the variant that repaired it lived in
   articol.css, and articol.css only loads on a single article. */
.post-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg-lift); border-radius: var(--r-lg); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--rule);
  transition: box-shadow .4s var(--ease), transform .4s var(--ease);
}
.post-card__media { aspect-ratio: 16 / 10; overflow: hidden; background: var(--plate); }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.post-card__body {
  display: flex; flex-direction: column; gap: .5rem; flex: 1;
  padding: clamp(1.1rem, 1.6vw, 1.5rem);
}
.post-card__date {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .08em;
  color: var(--faint); margin: 0;
}
.post-card__title {
  font-size: clamp(1.02rem, 1.25vw, 1.16rem); line-height: 1.3; margin: 0;
  /* Two lines, so every card in a row starts its standfirst on the same line. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card__title a { transition: color .25s var(--ease); }
.post-card__excerpt {
  margin: 0; color: var(--dim); font-size: .9rem; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Not a button: one accent-filled control per card, on twelve cards, is how a
   page stops having a call to action at all. This is a promise in text, and the
   whole card is the target. */
.post-card__more {
  margin-top: auto; padding-top: .9rem;
  font-family: var(--font-display); font-weight: 600; font-size: .86rem;
  color: var(--accent); display: inline-flex; align-items: center; gap: .45rem;
}
.post-card__more::after { content: "\2192"; transition: transform .35s var(--ease); }

/* The lead article carries a wider frame and a bigger headline, so three items
   read as a hierarchy rather than three equals. 3:2 made it 500px tall on a
   1440 page for one headline, which is a poster, not a card. */
.post-card--lead .post-card__media { aspect-ratio: 16 / 10; }
.post-card--lead .post-card__title {
  font-size: clamp(1.25rem, 1.9vw, 1.6rem); -webkit-line-clamp: 3;
}
.post-card--lead .post-card__body { padding: clamp(1.4rem, 2vw, 1.9rem); gap: .6rem; }

/* ---------- Specifications ----------
   A hairline under all twenty rows is the laziest datasheet layout there is, and
   it makes a long spec list unreadable. Each value gets its own block: label
   above in small caps, value below at reading size. Scans in a glance, groups
   naturally into columns, and stays legible on a phone. */
/* Borders live on the cells, not on a background showing through 1px gaps.
   The gap trick paints an empty grey tile wherever the last row runs out of
   content, which reads as missing data. */
.specs { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 0; }
.specs__row {
  display: block; padding: 1.15rem 1.35rem 1.25rem;
  border-top: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
.specs__row:last-child { border-right: 1px solid var(--rule); }
.specs { border-bottom: 1px solid var(--rule); border-right: 1px solid var(--rule); }
.specs__key {
  display: block; color: var(--faint); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; font-family: var(--font-mono); margin-bottom: .45rem;
}
.specs__val { display: block; font-size: 1rem; line-height: 1.45; color: var(--text); font-variant-numeric: tabular-nums; }

/* ---------- Breadcrumbs ---------- */
.breadcrumb { font-family: var(--font-mono); font-size: .74rem; color: var(--faint); padding-block: 1.4rem; letter-spacing: .04em; }
.breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; }
.breadcrumb li + li::before { content: "/"; margin-right: .5rem; color: var(--rule-lit); }
.breadcrumb a { transition: color .25s; }
.breadcrumb a:hover { color: var(--accent); }

/* ---------- Forms ---------- */
.field { display: grid; gap: .45rem; margin-bottom: 1.05rem; }
.field label { font-size: .8rem; color: var(--faint); letter-spacing: .02em; }
.field input, .field select, .field textarea {
  width: 100%; padding: .85rem 0; font: inherit; font-size: .95rem;
  color: var(--text); background: transparent;
  border: 0; border-bottom: 1px solid var(--rule); border-radius: 0;
  transition: border-color .3s var(--ease);
}
.field select { padding-right: 1rem; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-bottom-color: var(--accent);
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field textarea { min-height: 110px; resize: vertical; }
.field--check { display: flex; gap: .65rem; align-items: flex-start; margin-top: .4rem; }
.field--check input { width: auto; margin-top: .35rem; accent-color: var(--accent); }
.field--check label { font-size: .8rem; line-height: 1.5; }
.form-note { font-size: .8rem; color: var(--faint); }
.form-alert { padding: .85rem 1rem; border-radius: var(--r); margin-bottom: 1.2rem; font-size: .9rem; }
.form-alert--ok  { background: color-mix(in srgb, var(--ok) 10%, transparent); border: 1px solid var(--ok); }
.form-alert--err { background: color-mix(in srgb, var(--danger) 10%, transparent); border: 1px solid var(--danger); }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Footer ---------- */
.site-footer { border-top: 1px solid var(--rule); padding-block: clamp(56px, 7vw, 96px) 2rem; }
.site-footer__inner { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr; gap: clamp(2rem, 4vw, 3.5rem); }
.site-footer h4 {
  font-family: var(--font-mono); font-size: .7rem; text-transform: uppercase;
  letter-spacing: .18em; color: var(--faint); font-weight: 500; margin-bottom: 1.2rem;
}
.site-footer__menu { list-style: none; margin: 0; padding: 0; display: grid; gap: .65rem; font-size: .9rem; }
.site-footer__menu a { color: var(--dim); transition: color .25s; }
.site-footer__menu a:hover { color: var(--accent); }
.site-footer__contact { display: grid; gap: .55rem; font-size: .9rem; color: var(--dim); }
.site-footer__contact a { transition: color .25s; }
.site-footer__contact a:hover { color: var(--text); }
.site-footer__social { display: flex; gap: .5rem; margin-top: 1.4rem; }
.site-footer__social a {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--rule); border-radius: 50%; font-size: .78rem; color: var(--dim);
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.site-footer__social a:hover { border-color: var(--accent); color: var(--accent); }
.site-footer__anpc { display: flex; gap: .7rem; margin-top: 1.4rem; flex-wrap: wrap; }
.site-footer__anpc img { height: 36px; width: auto; opacity: .55; transition: opacity .3s; }
.site-footer__anpc a:hover img { opacity: 1; }
/* Stands in for a badge image until the file is added to assets/img. */
.site-footer__anpc-text {
  display: inline-block; font-size: .74rem; color: var(--dim);
  border: 1px solid var(--rule); border-radius: var(--r); padding: .45rem .7rem;
  transition: color .3s, border-color .3s;
}
.site-footer__anpc a:hover .site-footer__anpc-text { color: var(--text); border-color: var(--rule-lit); }
.site-footer__legal {
  margin-top: clamp(3rem, 5vw, 5rem); padding-top: 1.6rem; border-top: 1px solid var(--rule);
  font-size: .78rem; color: var(--faint);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.site-footer__legal a:hover { color: var(--dim); }

/* ---------- FAQ ---------- */
.faq-item { border-bottom: 1px solid var(--rule); padding: 1.3rem 0; }
.faq-item summary {
  cursor: pointer; font-weight: 500; font-family: var(--font-display); font-size: 1.05rem;
  list-style: none; display: flex; justify-content: space-between; gap: 1.5rem; align-items: center;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; color: var(--accent); font-size: 1.2rem; font-weight: 400; }
.faq-item[open] summary::after { content: "−"; }

/* ---------- Pagination ---------- */
.pagination { display: flex; gap: .35rem; justify-content: center; flex-wrap: wrap; margin-top: clamp(3rem, 5vw, 4.5rem); }
.pagination .page-numbers {
  min-width: 40px; height: 40px; display: grid; place-items: center; padding-inline: .75rem;
  border-radius: var(--r); font-size: .88rem; color: var(--dim);
  font-variant-numeric: tabular-nums;
  transition: background-color .25s, color .25s;
}
.pagination .page-numbers.current { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.pagination a.page-numbers:hover { background: var(--plate-2); color: var(--text); }

/* =========================================================================
   Motion. Slow, weighty, and with a no-JS and reduced-motion answer for each.
   ========================================================================= */

/* The start state only applies when JS is available, so without JS the content
   is visible — the no-JS state is the correct final content. */
.js-enabled .reveal { opacity: 0; transform: translateY(18px); }
.js-enabled .reveal.is-visible {
  opacity: 1; transform: none;
  transition: opacity .9s var(--ease), transform .9s var(--ease);
}

/* Stagger via nth-child: no per-element JS, no inline styles, nothing to
   recompute on resize. Capped so a 20-card grid still lands quickly. */
.js-enabled .reveal--stagger.is-visible > * { animation: rise .85s var(--ease) both; }
.js-enabled .reveal--stagger.is-visible > :nth-child(1) { animation-delay: 0s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(2) { animation-delay: .07s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(3) { animation-delay: .14s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(4) { animation-delay: .21s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(5) { animation-delay: .28s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(6) { animation-delay: .35s; }
.js-enabled .reveal--stagger.is-visible > :nth-child(n+7) { animation-delay: .4s; }
@keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }

/* A heading that wipes up from behind its own edge. The clip lives on a
   wrapper so the transform never touches the text's own layout. */
.reveal-mask { display: block; overflow: hidden; }
.js-enabled .reveal-mask > * { display: block; transform: translateY(105%); transition: transform 1.05s var(--ease); }
.js-enabled .reveal-mask.is-visible > *,
.js-enabled .is-visible .reveal-mask > * { transform: none; }

/* Product photography settles as it arrives — a slow scale-down reads as the
   object coming to rest, which is worth more here than a fade. */
.js-enabled .reveal--stagger.is-visible .card__media img { animation: settle 1.4s var(--ease) both; }
@keyframes settle { from { transform: scale(1.07); } to { transform: none; } }

/* Seamless marquee: JS clones the track once and the animation moves the pair
   by exactly -50%, so the seam is invisible. Each item carries its own
   trailing gap (margin-right, not a flex gap) so spacing across the seam
   matches the spacing everywhere else. */
/* The clone the script appends is a sibling of the track, so this box has to be
   a flex row: as a block it stacked the two copies vertically and the band
   rendered as the same words twice, one line above the other. */
.marquee { overflow: hidden; position: relative; display: flex; }
.marquee::before, .marquee::after { content: ""; position: absolute; top: 0; bottom: 0; width: clamp(60px, 12vw, 180px); z-index: 2; pointer-events: none; }
.marquee::before { left: 0;  background: linear-gradient(to right, var(--bg), transparent); }
.marquee::after  { right: 0; background: linear-gradient(to left,  var(--bg), transparent); }
.marquee__track { display: flex; width: max-content; flex: 0 0 auto; will-change: transform; }
.marquee__track > * { margin-right: var(--marquee-gap, 3.5rem); flex: 0 0 auto; }
.marquee.is-running .marquee__track { animation: marquee var(--marquee-duration, 46s) linear infinite; }
.marquee.is-paused  .marquee__track { animation-play-state: paused; }
/* Each copy travels its own full width and the copy behind it lands exactly
   where it left, so the seam is invisible. -50% belongs to the other way of
   building this (one track containing two sets), not to two sibling tracks. */
@keyframes marquee { from { transform: translate3d(0,0,0); } to { transform: translate3d(-100%,0,0); } }

/* ---------- Parallax layers ----------
   Driven by the scroll timeline itself rather than by a scroll handler. Three
   things follow from that: it runs off the main thread, it works for every
   parallax band on the page instead of only the first one, and each band is
   measured against its own position rather than against the top of the
   document (the old handler computed scrollY over the hero's height, which is
   meaningless for a band four thousand pixels down the page).

   Where the timeline is unsupported the layers simply sit still, which is what
   they already do for anyone who asked for reduced motion. */
[data-parallax] { position: relative; overflow: hidden; }

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* The scale is what buys the drift its headroom: at 1.08 there is 4% of
       overscan on each edge, so a 3% travel never exposes the layer's edge. */
    [data-parallax-media] {
      will-change: transform;
      animation: parallax-media linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
    /* The hero already fills the screen at rest, so it has no entry to animate
       across. Both of its layers run over its exit instead, which is the only
       part of its pass the reader ever sees. */
    .hero [data-parallax-media] { animation-range: exit 0% exit 100%; }
    [data-parallax-content] {
      will-change: transform, opacity;
      animation: parallax-content linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }
  }
}
@keyframes parallax-media {
  from { transform: translate3d(0, -3%, 0) scale(1.08); }
  to   { transform: translate3d(0,  3%, 0) scale(1.08); }
}
@keyframes parallax-content {
  from { transform: translate3d(0, 0, 0); opacity: 1; }
  to   { transform: translate3d(0, 36px, 0); opacity: .55; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1180px) {
  .site-footer__inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 1024px) {
  .split { grid-template-columns: 1fr; }
}
@media (max-width: 920px) {
  /* Parked in place, not off to the right. A fixed panel slid a full viewport
     sideways stays inside the document's scrollable overflow, and nothing can
     clip it back: a fixed element's containing block is the viewport, so
     overflow-x on body or html does not apply to it. The page then scrolls
     sideways by a whole screen on every phone. Opacity and a short vertical
     rise cost nothing horizontally; `visibility` keeps the closed menu's links
     out of the tab order. */
  .site-nav {
    position: fixed; inset: 76px 0 0; background: var(--bg);
    padding: 2rem var(--gutter) 4rem; overflow-y: auto;
    opacity: 0; visibility: hidden; transform: translateY(-10px);
    transition: opacity .3s var(--ease), transform .4s var(--ease), visibility 0s linear .4s;
  }
  .site-header.is-open .site-nav {
    opacity: 1; visibility: visible; transform: none;
    transition: opacity .3s var(--ease), transform .4s var(--ease), visibility 0s;
  }
  .site-nav__menu { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav__menu > li { border-bottom: 1px solid var(--rule); }
  .site-nav__menu > li > a { padding: 1.15rem 0; font-size: 1.15rem; color: var(--text); }
  .site-nav__menu > li > a::after { display: none; }
  .site-nav__menu .sub-menu {
    position: static; opacity: 1; visibility: visible; transform: none;
    background: none; border: 0; padding: 0 0 .9rem .9rem; min-width: 0;
  }
  .site-nav__toggle { display: flex; }
  .site-header__cta .btn--outline, .site-header__phone { display: none; }
  .mobile-cta { display: flex; }
  body { padding-bottom: 70px; }
}
@media (max-width: 620px) {
  .site-footer__inner { grid-template-columns: 1fr; }
  .specs__row { grid-template-columns: 1fr; gap: .15rem; padding: .8rem 0; }
  .site-footer__legal { flex-direction: column; gap: .5rem; }
  .head-row { align-items: flex-start; }
}

/* Hover-dependent effects only with a real pointer. */
@media (hover: hover) and (pointer: fine) {
  .post-card:hover { box-shadow: inset 0 0 0 1px var(--rule-lit); transform: translateY(-3px); }
  .post-card:hover .post-card__media img { transform: scale(1.045); }
  .post-card:hover .post-card__more::after { transform: translateX(4px); }
  .btn--quiet:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
  .btn--accent:hover { background: #6FE3F0; transform: translateY(-1px); }
  .btn--outline:hover { border-color: var(--text); }
  .btn--ghost:hover { background: var(--rule); }
  .btn--text:hover::after { transform: translateX(5px); }
  .link-line:hover::after { transform: scaleX(0); }
  .link-line:hover::before { transform: scaleX(1); }
  .card:hover .card__media img { transform: scale(1.045); }
  .card:hover .card__title a { color: var(--accent); }
  .marquee:hover .marquee__track { animation-play-state: paused; }
}

/* Reduced motion is an off switch, not a slowdown: collapse to the final state. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js-enabled .reveal { opacity: 1; transform: none; }
  .js-enabled .reveal--stagger.is-visible > * { opacity: 1; transform: none; }
  .js-enabled .reveal-mask > * { transform: none !important; }
  .marquee__track { transform: none !important; }
  .marquee { overflow-x: auto; }
}
