/* ============================================================
   LD NAILS & SPA
   Three directions from the Claude Design pass. ONE DOM —
   every difference below is a token value, never markup.

     midnight  Midnight Set        near-black + antique gold
     pink      Salon Pink          white + hot pink, hard edges
     warm      Warm Neighborhood   cream + rust, soft and round

   Token names follow the design's own vocabulary rather than
   the starter's --c-* set. Revisions are worked live against
   these names; this block is the reference, and the client's
   own set and spacing steps are listed in design-notes.md.
   ============================================================ */

:root {
  --wrap: clamp(18px, 5vw, 40px);   /* page gutter, not themed */
  --pill-clear: 96px;               /* space the fixed call pill needs at the page end */
}

/* Bare `:root` carries the default theme as well as [data-theme="midnight"], so a
   document that never gets the attribute still renders. layout.njk always sets it,
   but the CMS preview iframe does not — without this, every token there falls back
   to its initial value and the preview is worse than no preview at all.
   Specificity is identical to the other two blocks, which sit after this one, so
   pink and warm still win when their attribute is present. */
:root,
[data-theme="midnight"] {
  --bg: #09080a; --bg2: #100e14; --surf: #15121b;
  --ink: #f6f1ea; --ink2: #f6f1ea; --dim: #a299ab; --dim2: #a299ab; --line: #2b2533;
  --acc: #d8b25c; --acc2: #d8b25c; --acc-ink: #09080a; --btn-bd: #d8b25c;
  --fd: 'Cormorant Garamond', Georgia, serif;
  --fb: 'Jost', system-ui, sans-serif;
  --h1: clamp(38px, 15cqi, 80px); --h2: clamp(30px, 7.4vw, 54px); --h3: clamp(20px, 4.6vw, 26px);
  --lead: clamp(16px, 4.2vw, 20px); --base: clamp(15px, 3.9vw, 17px); --small: 14px; --tiny: 11px;
  --hw: 400; --hls: 1.02; --tr: .2em; --up: uppercase; --hsp: 0em;
  --r: 2px; --r-img: 2px; --r-btn: 999px; --bw: 1px; --sh: none;
  --sp: clamp(66px, 14vw, 124px); --gal-gap: 6px;
  --img-filter: saturate(1.06) contrast(1.04); --maxw: 1180px;
}

[data-theme="pink"] {
  --bg: #ffffff; --bg2: #ff2e8b; --surf: #ffffff;
  --ink: #121012; --ink2: #ffffff; --dim: #5d585c; --dim2: rgba(255,255,255,.92); --line: #121012;
  --acc: #ff2e8b; --acc2: #121012; --acc-ink: #ffffff; --btn-bd: #121012;
  --fd: 'Archivo Black', Impact, sans-serif;
  --fb: 'Archivo', system-ui, sans-serif;
  --h1: clamp(32px, 11.5cqi, 62px); --h2: clamp(29px, 7vw, 50px); --h3: clamp(18px, 4.2vw, 23px);
  --lead: clamp(16px, 4.1vw, 19px); --base: clamp(15px, 3.9vw, 17px); --small: 14px; --tiny: 11px;
  --hw: 400; --hls: .94; --tr: .04em; --up: uppercase; --hsp: -.02em;
  --r: 0px; --r-img: 0px; --r-btn: 0px; --bw: 3px; --sh: 6px 6px 0 var(--ink);
  --sp: clamp(54px, 11vw, 88px); --gal-gap: 10px;
  --img-filter: saturate(1.1); --maxw: 1140px;
}

[data-theme="warm"] {
  --bg: #f7f1e8; --bg2: #eee3d4; --surf: #fffdf9;
  --ink: #312619; --ink2: #312619; --dim: #7c6a56; --dim2: #7c6a56; --line: #e2d5c2;
  --acc: #a55c33; --acc2: #a55c33; --acc-ink: #fffdf9; --btn-bd: #a55c33;
  --fd: 'Newsreader', Georgia, serif;
  --fb: 'Karla', system-ui, sans-serif;
  --h1: clamp(34px, 13.5cqi, 66px); --h2: clamp(27px, 6.2vw, 42px); --h3: clamp(19px, 4.3vw, 24px);
  --lead: clamp(16px, 4.1vw, 19px); --base: clamp(15px, 3.9vw, 17px); --small: 14px; --tiny: 11.5px;
  --hw: 500; --hls: 1.12; --tr: .07em; --up: none; --hsp: 0em;
  --r: 20px; --r-img: 18px; --r-btn: 999px; --bw: 1px; --sh: 0 10px 28px rgba(49,38,25,.09);
  --sp: clamp(60px, 13vw, 108px); --gal-gap: 14px;
  --img-filter: saturate(.98) brightness(1.02); --maxw: 1040px;
}

/* ============================================================
   BASE
   ============================================================ */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--fb);
  font-size: var(--base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
  /* The call pill's clearance lives on the footer, not here. Padding on the body
     sits BELOW the footer and paints in --bg, which showed as a strip of page
     background under a --bg2 footer on every tab (tasks/lessons.md). */
  transition: background .25s ease, color .25s ease;
}

img { display: block; max-width: 100%; }
a { color: var(--acc); }
a:hover { color: var(--ink); }
h1, h2, h3, h4 {
  font-family: var(--fd); font-weight: var(--hw);
  line-height: var(--hls); letter-spacing: var(--hsp);
  margin: 0;
}
:focus-visible { outline: 3px solid var(--acc); outline-offset: 2px; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--wrap); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@keyframes ldFade { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }

/* ============================================================
   DEFENSIVE PATTERNS — the layout survives any allowed content.
   CMS field limits (admin/config.yml) + these rules together
   mean clients cannot break the site from the editor.
   ============================================================ */

/* Every element that renders client-entered text belongs in this list. An
   unclassed element holding CMS content is a layout bug waiting to happen —
   a long email in an unclassed <p> is exactly how .contact overflowed once. */
.eyebrow, .hero__title, .hero__accent, .hero__sub, .hero__hours, .section__title, .section__note,
.svc-group__name, .svc__name, .svc__price, .svc__desc,
.gallery__caption, .about__text, .quote__text, .quote__source,
.contact__address, .contact__phone, .contact__hours span, .contact__booking,
.site-footer__name, .site-footer__tagline, .site-footer__legal,
.btn, .call-pill__label, .svc-toggle-all, .tabs__tab {
  overflow-wrap: anywhere;
}

.clamp-2, .clamp-3, .clamp-4, .clamp-8 {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.clamp-2 { -webkit-line-clamp: 2; }
.clamp-3 { -webkit-line-clamp: 3; }
.clamp-4 { -webkit-line-clamp: 4; }
/* clamp-8 holds the 280-character review maximum at every width. Hard rule 10
   makes review length a build-time editorial decision, so the clamp is a
   backstop against a raised cap — it must never trim a chosen excerpt. */
.clamp-8 { -webkit-line-clamp: 8; }

/* Nail photography is shot vertically. Portrait frames keep the fingers and the
   design in view; the storefront and interiors are landscape and get 4:3. */
.gallery__item img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.hero__media img   { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.about__media img, .contact__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.gallery__item img, .hero__media img, .about__media img, .contact__media img {
  border-radius: var(--r-img); filter: var(--img-filter);
}

/* ============================================================
   PREVIEW THEME BAR (demo mode only) — ours, not the design's
   ============================================================ */

.theme-bar {
  position: sticky; top: 0; z-index: 60;
  background: #100f14; border-bottom: 1px solid #29252f;
}
.theme-bar__inner {
  max-width: 1180px; margin: 0 auto; padding: 8px 14px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.theme-bar__label {
  font-family: 'Jost', system-ui, sans-serif; font-size: 10.5px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: #79737f;
}
.theme-bar__btn {
  font: inherit; font-family: 'Jost', system-ui, sans-serif; font-size: 12px; font-weight: 500;
  border: 1px solid #33303a; border-radius: 999px; padding: 6px 13px;
  background: transparent; color: #9b95a2; cursor: pointer; min-height: 34px;
}
.theme-bar__btn.is-active { background: #f3efe9; color: #121015; }

/* ============================================================
   HEADER + TABS
   ============================================================ */

.site-header { background: var(--bg); }
.site-header__inner {
  padding-top: 20px; padding-bottom: 16px;
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
}
.site-header__brand {
  font-family: var(--fd); font-size: clamp(21px, 5.2vw, 28px); font-weight: var(--hw);
  line-height: 1.05; letter-spacing: var(--hsp); color: var(--ink); text-decoration: none;
  overflow-wrap: anywhere;
}
.site-header__brand:hover { color: var(--acc); }
.site-header__tagline {
  font-size: var(--tiny); letter-spacing: var(--tr); text-transform: var(--up); color: var(--dim);
  overflow-wrap: anywhere;
}

.tabs {
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  border-top: var(--bw) solid var(--line); border-bottom: var(--bw) solid var(--line);
}
.tabs__list {
  max-width: var(--maxw); margin: 0 auto; padding-inline: var(--wrap);
  display: flex; gap: clamp(16px, 3.4vw, 30px); overflow-x: auto;
}
.tabs__tab {
  flex: none; background: transparent; border: 0; border-bottom: 2px solid transparent;
  padding: 14px 0; cursor: pointer;
  font: inherit; font-size: var(--small); font-weight: 600;
  letter-spacing: var(--tr); text-transform: var(--up); white-space: nowrap;
  color: var(--dim); text-decoration: none;
}
.tabs__tab[aria-selected="true"] { color: var(--acc); border-bottom-color: var(--acc); }

/* Panels are visible by default so the page works with no JS at all.
   js/tabs.js opts in to tab behaviour and only then hides the inactive ones. */
.panel { display: block; background: var(--bg); }
.panel__inner { padding-block: var(--sp); }
[data-tabs-ready] .panel[hidden] { display: none; }

.eyebrow {
  font-size: var(--tiny); font-weight: 600; letter-spacing: var(--tr);
  text-transform: var(--up); color: var(--acc); margin: 0;
}
.section__title { font-size: var(--h2); color: var(--ink); }
.section__note { margin: 0; font-size: var(--small); color: var(--dim); }
.section__head { display: flex; flex-direction: column; gap: 10px; max-width: 34ch; }

/* ============================================================
   HOME / HERO
   ============================================================ */

.hero { display: flex; flex-wrap: wrap; gap: clamp(28px, 5vw, 60px); align-items: center; }
.hero__copy {
  flex: 1 1 330px; min-width: 0; container-type: inline-size;
  display: flex; flex-direction: column; align-items: flex-start; gap: clamp(16px, 3vw, 24px);
}
/* text-wrap: balance so the accented ENDING is not split by the line break. Without it
   the browser breaks at the last opportunity that fits, which put "Welcome to LD" on
   line one and "Nails & Spa" on line two — the business name cut in half, at every
   width. Measured: 2 accent line boxes before, 1 after, at 360/768/1280.
   `white-space: nowrap` on the accent fixes the same symptom and is the wrong fix: at
   the 30-character cap an unbreakable token then overflowed the copy column, the panel
   AND the document at all three widths. Balance keeps the accent whole at real content
   and still lets an unbreakable token break, so nothing overflows at the cap.
   Same family of decision as `text-wrap: pretty` on body, a few rules up. */
.hero__title { font-size: var(--h1); color: var(--ink); text-wrap: balance; }

/* The accented ENDING of the hero headline (home.heading_accent). One token, so the
   accent is theme-expressive for free — antique gold in Midnight, hot pink in Salon
   Pink, rust in Warm — rather than being stated three times and drifting.
   It is also exactly what the CMS label promises the client: "shown in your theme's
   colour". A treatment that needed the label reworded would have been the wrong one.

   Two alternatives were rendered in all three themes and rejected on the evidence:
   an underline, whose thickness had to come from --bw and therefore read as a 1px
   hairline under 80px type in Midnight and Warm while Pink got a deliberate 3px; and
   a filled highlight, which was too loud beside an untouched section AND changed where
   the line broke, splitting the business name again in two of the three themes. */
.hero__accent { color: var(--acc); }
.hero__sub { margin: 0; max-width: 46ch; font-size: var(--lead); line-height: 1.5; color: var(--dim); }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.hero__hours { font-size: var(--small); color: var(--dim); }
.hero__media { flex: 1 1 300px; min-width: 0; }
.hero__media img { border: var(--bw) solid var(--line); box-shadow: var(--sh); }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--acc); color: var(--acc-ink);
  border: var(--bw) solid var(--btn-bd); border-radius: var(--r-btn);
  padding: 15px 26px; font: inherit; font-size: var(--base); font-weight: 700;
  text-decoration: none; cursor: pointer; box-shadow: var(--sh); min-height: 44px;
  max-width: 100%; text-align: center; justify-content: center;
}
.btn:hover { color: var(--acc-ink); filter: brightness(1.07); }
.btn--ghost {
  background: transparent; color: var(--ink);
  border-color: var(--line); box-shadow: none; font-weight: 500;
}
.btn--ghost:hover { color: var(--acc); border-color: var(--acc); filter: none; }

/* ============================================================
   SERVICES — accordion of four groups
   ============================================================ */

.svc-head {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: flex-end; justify-content: space-between;
  margin-bottom: clamp(24px, 4vw, 40px);
}
.svc-toggle-all {
  border: var(--bw) solid var(--line); background: transparent; color: var(--ink);
  border-radius: var(--r-btn); padding: 11px 20px;
  font: inherit; font-size: var(--small); font-weight: 500;
  cursor: pointer; white-space: nowrap; min-height: 44px;
}
.svc-toggle-all:hover { border-color: var(--acc); color: var(--acc); }

.svc-groups {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(12px, 2.4vw, 20px); align-items: start;
}
.svc-group {
  border: var(--bw) solid var(--line); border-radius: var(--r);
  background: var(--surf); box-shadow: var(--sh); overflow: hidden;
}
.svc-group__summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 20px; cursor: pointer; list-style: none;
}
.svc-group__summary::-webkit-details-marker { display: none; }
.svc-group__label { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.svc-group__name {
  font-family: var(--fd); font-size: var(--h3); font-weight: var(--hw);
  line-height: 1.15; letter-spacing: var(--hsp); color: var(--ink);
}
.svc-group__count {
  font-size: var(--tiny); letter-spacing: var(--tr); text-transform: var(--up); color: var(--dim);
}
.svc-group__sign {
  flex: none; font-size: 24px; line-height: 1; color: var(--acc);
  transition: transform .18s ease;
}
.svc-group[open] .svc-group__sign { transform: rotate(45deg); }
.svc-group__body { padding: 0 20px 16px; animation: ldFade .22s ease; }

.svc {
  display: grid; grid-template-columns: 1fr auto; gap: 3px 16px;
  align-items: baseline; padding: 13px 0; border-top: 1px solid var(--line);
}
/* No min-width:0 here. The 1fr column would then shrink below the width of a
   single broken character, and the name overflows its own cell by a few pixels.
   Letting min-content govern costs nothing — overflow-wrap already reduces
   min-content to one character. */
.svc__name { font-weight: 500; }
.svc__price { font-weight: 600; color: var(--acc); flex: none; max-width: 100%; }
.svc__desc { grid-column: 1 / -1; font-size: var(--small); color: var(--dim); }

/* ============================================================
   GALLERY
   ============================================================ */

.gallery {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--gal-gap);
}
.gallery__link { display: block; text-decoration: none; color: inherit; }
.gallery__caption {
  display: block; margin-top: 8px;
  font-size: var(--tiny); letter-spacing: var(--tr); text-transform: var(--up); color: var(--dim);
}

/* ============================================================
   ABOUT
   ============================================================ */

.panel--alt { background: var(--bg2); color: var(--ink2); }
.panel--alt .section__title, .panel--alt .about__text { color: var(--ink2); }
.panel--alt .section__note { color: var(--dim2); }
.about { display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 44px); align-items: flex-start; }
.about__text { flex: 1 1 380px; min-width: 0; margin: 0; font-size: var(--lead); line-height: 1.62; color: var(--ink2); }
.about__media { flex: 1 1 260px; min-width: 0; display: grid; gap: var(--gal-gap); }

/* ============================================================
   REVIEWS
   ============================================================ */

.quotes { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(12px, 2.4vw, 20px);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.quote {
  display: flex; flex-direction: column; gap: 12px;
  border: var(--bw) solid var(--line); border-radius: var(--r);
  background: var(--surf); box-shadow: var(--sh); padding: 22px 20px;
}
.quote__stars { color: var(--acc); letter-spacing: .18em; font-size: 15px; }
.quote__text { margin: 0; flex: 1; font-size: var(--base); line-height: 1.6; color: var(--ink); }
.quote__source { font-size: var(--tiny); letter-spacing: var(--tr); text-transform: var(--up); color: var(--dim); }

/* ============================================================
   VISIT / CONTACT
   ============================================================ */

.contact { display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 44px); align-items: flex-start; }
.contact__col { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 22px; }
.contact__media img { border: var(--bw) solid var(--line); box-shadow: var(--sh); }
.contact__label {
  display: block; font-size: var(--tiny); font-weight: 600;
  letter-spacing: var(--tr); text-transform: var(--up); color: var(--dim);
}
.contact__phone {
  font-family: var(--fd); font-size: clamp(28px, 7vw, 42px); font-weight: var(--hw);
  line-height: 1.1; color: var(--acc); text-decoration: none;
}
.contact__address { font-size: var(--lead); line-height: 1.45; color: var(--ink); font-style: normal; }
.contact__hours { list-style: none; margin: 8px 0 0; padding: 0; max-width: 420px; }
.contact__hours li {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 7px 0; border-bottom: 1px solid var(--line);
}
.contact__hours span:last-child { color: var(--dim); text-align: right; }

.contact__form {
  flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 16px;
  background: var(--surf); border: var(--bw) solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh); padding: clamp(20px, 4vw, 28px);
}
.contact__form label { display: grid; gap: 6px; }
.contact__form input, .contact__form select, .contact__form textarea {
  font: inherit; padding: 12px; width: 100%;
  border: var(--bw) solid var(--line); border-radius: calc(var(--r) / 2);
  background: var(--bg); color: var(--ink);
}

/* ============================================================
   FOOTER + FLOATING CALL
   ============================================================ */

.site-footer {
  background: var(--bg2); color: var(--ink2);
  border-top: var(--bw) solid var(--line);
}
.site-footer__inner {
  padding-top: clamp(36px, 7vw, 64px);
  /* Carries the call pill's clearance so the footer's own background reaches the
     bottom of the page and the footer reads as the end of it. The pill floats in
     this padding — the normal floating-action-button relationship. */
  padding-bottom: max(clamp(36px, 7vw, 64px), var(--pill-clear));
  display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-end; justify-content: space-between;
}
.site-footer__name {
  font-family: var(--fd); font-size: clamp(22px, 5.4vw, 30px); font-weight: var(--hw);
  line-height: 1; letter-spacing: var(--hsp); color: var(--ink2);
}
.site-footer__tagline { font-size: var(--small); color: var(--dim2); }
.site-footer__social { display: flex; gap: 18px; flex-wrap: wrap; }
.site-footer__social a { font-size: var(--small); color: var(--ink2); text-underline-offset: 4px; }
.site-footer__social a:hover { color: var(--acc2); }
.site-footer__legal { font-size: var(--tiny); color: var(--dim2); }

/* Global, outside the panels: the phone is the only conversion path on this
   site, so it stays reachable from every tab. */
/* Anchored on BOTH edges on purpose. A fixed box with only `left` set is
   shrink-to-fit against the space from that edge to the containing block's right
   edge — `left: 50%` sized this pill against 50vw, so "Call (778) 754-7488" wrapped
   to two lines at 360px and had exactly zero slack at 390px. `transform` re-centres
   after layout, far too late, and max-width never got to apply. Both edges + auto
   margins give it the full viewport to shrink-wrap inside. (tasks/lessons.md) */
.call-pill {
  position: fixed; left: 16px; right: 16px; bottom: 18px; z-index: 55;
  width: fit-content; margin-inline: auto;
  /* Block with inline content, NOT flex: the label and the number have to be able to
     fall onto separate lines when a maxed-out label leaves no room. Flex items do not
     wrap against each other, they overflow. */
  display: block; text-align: center;
  background: var(--acc); color: var(--acc-ink);
  border: var(--bw) solid var(--btn-bd); border-radius: 999px;
  padding: 14px 26px; font-weight: 700; font-size: 15px;
  text-decoration: none; box-shadow: 0 12px 34px rgba(0,0,0,.3);
}
.call-pill:hover { color: var(--acc-ink); filter: brightness(1.07); }
/* The number is one indivisible token. A maxed-out label may push it to a second
   line — that backstop stays — but it never breaks mid-number. */
.call-pill__num { white-space: nowrap; }

/* ============================================================
   LIGHTBOX — a JS upgrade. Without JS the gallery links open the
   image directly, so nothing here is required to see a photo.
   ============================================================ */

.lightbox {
  position: fixed; inset: 0; z-index: 80; display: none;
  background: rgba(6,5,7,.94); padding: 24px;
  align-items: center; justify-content: center;
}
.lightbox[open], .lightbox.is-open { display: flex; }
.lightbox__inner { max-width: min(92vw, 720px); display: flex; flex-direction: column; gap: 14px; }
.lightbox__img { width: 100%; max-height: 76vh; object-fit: contain; border-radius: var(--r-img); }
.lightbox__cap { margin: 0; text-align: center; font-size: 13px; line-height: 1.5; color: #e8e3dc; }
.lightbox__close {
  position: absolute; top: 16px; right: 16px;
  background: transparent; border: 1px solid #6b6570; border-radius: 999px;
  color: #e8e3dc; font: inherit; font-size: 14px; padding: 8px 16px; cursor: pointer; min-height: 44px;
}

@media (min-width: 760px) {
  .contact__hours { max-width: 380px; }
}
