/* ==========================================================================
   SVOD — stomatološka ordinacija (koncept)
   --------------------------------------------------------------------------
   One file, no preprocessor, no build step. Custom properties ARE the token
   system. Sections run in page order; find-by-scrolling has to work.

   Token sheet and the measured contrast table: ../../docs/tokens.md
   Direction and the rejected log:              ../../docs/design-direction.md

   THREE THINGS THAT BITE
     · Mobile overrides live at the END of this file. Same specificity means
       later wins.
     · The radius system is 3px structural + ONE arch + ONE pill. The pill is on
       the primary CTA and nothing else.
     · This is a LIGHT ground. Washes are rgba(24,34,28,…) — ink over paper,
       never white over dark. Copying a rule from the dark starter without
       flipping it produces an invisible hairline.
   ========================================================================== */


/* ============ FONTS ============
   Self-hosted variable woff2. A font CDN violates font-src 'self' and fails
   silently. Both subsets are declared: Serbian č ć š ž đ live in latin-ext
   (U+0100–02BA) and render as fallback glyphs mid-word without it. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/fraunces-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/fraunces-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ============ TOKENS ============ */
:root {
  /* colour — one accent hue, everything derived from it */
  --accent-hue: 156;
  --accent:      oklch(0.460 0.100 var(--accent-hue));   /* #196840 · 6.08:1 on ground */
  --accent-sink: oklch(0.360 0.090 var(--accent-hue));   /* #004a28 · fills, pressed */
  --accent-lift: oklch(0.620 0.110 var(--accent-hue));   /* #469a6a · boundaries. NEVER text */

  /* ink — three levels. The third is the one that fails; it is at the floor. */
  --ink:      oklch(0.240 0.018 var(--accent-hue));      /* 14.65:1 */
  --ink-soft: oklch(0.440 0.015 var(--accent-hue));      /*  6.92:1 */
  --ink-mute: oklch(0.500 0.014 var(--accent-hue));      /*  5.32:1 — do not lighten */

  /* ground — warm porcelain at 0.011 chroma. Reads as paper, not as a colour. */
  --ground:      oklch(0.963 0.011 85);
  --ground-lift: oklch(0.985 0.008 85);
  --ground-sink: oklch(0.925 0.014 85);

  /* surfaces — translucent INK washes over the ground, never opaque greys */
  --wash: rgba(24, 34, 28, 0.026);

  /* strokes — two decorative brightnesses plus one that must be findable */
  --stroke:        rgba(24, 34, 28, 0.14);
  --stroke-quiet:  rgba(24, 34, 28, 0.09);
  --stroke-field:  rgba(24, 34, 28, 0.55);   /* 3.60:1 — inputs, real boundaries */

  /* depth — one drop, under the primary CTA and nothing else */
  --drop: 0 2px 0 rgba(0, 74, 40, 0.28), 0 10px 22px -12px rgba(24, 34, 28, 0.55);

  /* shape */
  --r-structural: 3px;
  --r-arch: 999px 999px var(--r-structural) var(--r-structural);   /* the motif */
  --r-pill: 999px;                                                 /* primary CTA only */

  /* motion — one duration for micro-states, one curve. The only other motion
     on the page is the arch set-piece, which owns its own 1.8s in app.js. */
  --t-micro: 0.16s;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* space */
  --gutter: 40px;
  --section-gap: clamp(64px, 8vw, 116px);

  /* type */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-sans: "Instrument Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;
}


/* ============ BASE ============ */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

/* The surfaces we did not draw.
   Text selection, the caret, form control accents and the underline offset all
   ship with browser defaults that belong to no design system — a blue Windows
   selection over a porcelain page is the single loudest un-designed thing left
   on it. Cheap to fix, invisible when right, and the one thing that most
   reliably separates a page that was built from one that was assembled.
   Added 2026-09-22 from Impeccable's craft floor (pbakaus/impeccable, Apache
   2.0); written here in our own tokens, nothing vendored.
   `tabular-nums` — the fourth item on that list — was already correct on the
   price list and the plan sheet. */
::selection {
  background: oklch(0.460 0.100 var(--accent-hue) / 0.18);
  color: var(--ink);
}
:root {
  accent-color: var(--accent);   /* checkbox, radio, the form's own controls */
  caret-color: var(--accent);    /* the text cursor in the contact form */
}
a {
  text-underline-offset: 0.16em;
  text-decoration-thickness: 1px;
}

/* The full-bleed breakout below uses `calc(50% - 50vw)`. `50vw` INCLUDES the
   scrollbar while `50%` of the container does not, so whenever a vertical
   scrollbar is present those elements overshoot by half its width on each side
   and the page gains ~8px of horizontal scroll. Found in review 2026-09-21
   (scrollWidth 1017 vs clientWidth 1009).

   `overflow-x: clip` and NOT `hidden`: `hidden` makes html a scroll container,
   which silently breaks `position: sticky` on the nav. `clip` does not. */
html { overflow-x: clip; }

/* Body takes `clip` too, for the same reason. Until 2026-09-25 it had
   `hidden`, and the nav never stuck: a body's overflow only passes to the
   window while html's is `visible`, so once html had `clip` the body's
   `hidden` stayed on the body and made IT the scroll container. The nav
   stuck to the body, which never scrolls. `clip` cuts the sideways overflow
   off the same way and makes no scroll container, so the nav sticks to the
   window. `hidden` stays first as the fallback for a browser without `clip`:
   there html's `clip` is dropped too, so the body's `hidden` passes to the
   window as it used to, and the nav still sticks. */
body {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.62;
  color: var(--ink);
  background: var(--ground);
  min-height: 100vh;
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, .display, .brand-name { font-family: var(--font-display); }
em { font-style: normal; }
button { font-family: inherit; cursor: pointer; }
a.btn, a.nav-pill, a.brand, a.channel { text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: 10px 16px;
  background: var(--ground-lift);
  color: var(--ink);
  border: 1px solid var(--stroke-field);
  border-radius: var(--r-structural);
}
.skip-link:focus { left: 12px; top: 12px; }

/* Sticky nav: every in-page target needs this or the heading lands underneath */
[id] { scroll-margin-top: 96px; }


/* ============ BACKGROUND ============
   Two layers, both nearly invisible, both doing a job: a warm wash that lifts
   the top of the page off the ground colour, and a hairline column grid that
   exists behind the hero and is gone before it reaches body copy. */
.site-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--ground);
}
.bg-wash {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 90% 55% at 72% -6%, oklch(0.96 0.032 var(--accent-hue) / 0.55), transparent 62%),
    radial-gradient(ellipse 70% 40% at 8% 0%, oklch(0.985 0.020 85 / 0.9), transparent 60%);
}
.bg-rules {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(90deg, rgba(24, 34, 28, 0.05) 1px, transparent 1px);
  background-size: 152px 100%;
  background-position: center top;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 62vh);
          mask-image: linear-gradient(180deg, #000 0%, transparent 62vh);
}


/* ============ DEMO STRIP ============
   The concept disclosure. It is on every view deliberately: the practice, the
   people and the prices below it are invented. */
.demo-strip {
  position: relative;
  z-index: 2;
  background: var(--ground-sink);
  border-bottom: 1px solid var(--stroke-quiet);
}
.demo-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 8px var(--gutter);
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 12.5px;
  color: var(--ink-mute);
}
.demo-inner p { margin: 0; min-width: 0; }
/* A bordered badge, so caps are the right shape here — it is a stamp, not a
   label above a heading. Tracking eased 0.14em -> 0.10em only for legibility. */
.demo-tag {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-lift);
  border-radius: var(--r-structural);
  padding: 2px 7px;
}
.demo-link {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--stroke);
}
.demo-link:hover { color: var(--accent); border-bottom-color: var(--accent-lift); }

/* ---- 44x44 tap targets, at zero visual cost -------------------------------
   Four secondary links sat under 44x44: the concept credit, the brand lockup,
   the phone/e-mail values and the footer utility links. Padding them to 44px
   would have made the disclosure strip and the footer visibly taller for no
   reason a sighted mouse user could see.

   Instead each one keeps its rendered size and grows an invisible centred hit
   area. The pointer target is 44x44; the design is unchanged. The parent needs
   position: relative and the pseudo-element must sit under nothing clickable,
   which is why this is a short explicit list rather than a blanket rule. */
.demo-link, .brand, .channel-value, .u-link { position: relative; }
.demo-link::after,
.brand::after,
.channel-value::after,
.u-link::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  min-width: 44px;
  height: 100%;
  min-height: 44px;
}


/* ============ NAV ============ */
.nav-shell {
  position: sticky;
  top: 0;
  z-index: 50;
  padding: 0 var(--gutter);
  background: oklch(0.963 0.011 85 / 0.82);
  backdrop-filter: blur(12px) saturate(1.2);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  border-bottom: 1px solid var(--stroke);
}
.nav-inner {
  max-width: 1240px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 13px 0;
}

.brand { display: flex; align-items: center; gap: 11px; min-width: 0; }

/* THE MOTIF at its smallest: an arch. Solid accent, flat foot, and it still
   reads at 16px — which is the test the mark had to pass. */
.brand-mark {
  width: 22px; height: 26px;
  flex-shrink: 0;
  background: var(--accent);
  border-radius: var(--r-arch);
  position: relative;
}
.brand-mark::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 5px;
  transform: translateX(-50%);
  width: 8px; height: 11px;
  background: var(--ground);
  border-radius: 999px 999px 1px 1px;
}
.brand-mark.sm { width: 18px; height: 21px; }
.brand-mark.sm::after { width: 6px; height: 9px; bottom: 4px; background: var(--ground-sink); }

.brand-name {
  display: flex; flex-direction: column;
  line-height: 1;
  min-width: 0;
}
.brand-name {
  color: var(--ink);
  font-size: 20px; font-weight: 600; letter-spacing: 0.02em;
}
/* Part of the brand lockup, not an eyebrow: it is the descriptor that sits
   under the wordmark and it is how a Serbian visitor knows this is an
   ordinacija at all. Caps stay; 10.5px was too small for the Š and the Č. */
.brand-name em {
  font-family: var(--font-sans);
  font-size: 11px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 5px;
}

.nav-items { display: flex; justify-content: center; gap: 4px; flex: 1; min-width: 0; }
.nav-pill {
  position: relative;
  white-space: nowrap;   /* a wrapped nav label makes the sticky bar two rows tall */
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-soft);
  padding: 7px 11px;
  border-radius: var(--r-structural);
  transition: color var(--t-micro) var(--ease), background var(--t-micro) var(--ease);
}
.nav-pill:hover { color: var(--ink); background: var(--wash); }
.nav-pill.active { color: var(--ink); }
.nav-pill.active::after {
  content: "";
  position: absolute; left: 11px; right: 11px; bottom: 1px;
  height: 2px;
  background: var(--accent);
}


/* ============ BUTTONS ============
   Two variants. ONE primary per view — the pill is the shape signature and it
   stops meaning anything if three of them share a screen. */
.btn {
  display: inline-flex;
  align-items: center; justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  font-size: 14px; font-weight: 600; letter-spacing: 0.005em;
  border: 1px solid;
  border-radius: var(--r-structural);
  white-space: nowrap;
  transition: transform var(--t-micro) var(--ease), background var(--t-micro) var(--ease),
              border-color var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.btn.lg { padding: 14px 28px; font-size: 15.5px; }
.btn.sm { padding: 7px 14px; font-size: 13px; }

.btn.primary {
  border-radius: var(--r-pill);            /* the one pill in the design */
  color: var(--ground-lift);
  background: var(--accent);
  border-color: var(--accent-sink);
  box-shadow: var(--drop);
}
.btn.primary:hover { background: var(--accent-sink); transform: translateY(-1px); }
.btn.primary:active { transform: translateY(0); }

.btn.ghost {
  color: var(--ink);
  background: transparent;
  border-color: var(--stroke-field);
}
.btn.ghost:hover { background: var(--wash); border-color: var(--accent); color: var(--accent); }


/* ============ TYPE ============
   Every size on the site is here. Tracking tightens as size grows, line height
   loosens as size shrinks, labels take wide positive tracking. */
.display {
  margin: 20px 0 24px;
  font-size: clamp(38px, 5.2vw, 66px);
  line-height: 1.03;
  letter-spacing: -0.022em;
  font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
  max-width: 15ch;
}
.display em { color: var(--accent); }

.lede {
  margin: 0;
  font-size: clamp(17px, 1.5vw, 19.5px);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 52ch;
  text-wrap: pretty;
}

/* Section eyebrows. Kept, because they name the section a nav pill links to —
   but softened out of the "tracked-caps" shape: 0.14em at 11.5px is the AI
   eyebrow chip, and in Serbian the marks on Č Ć Ž Š start colliding with the
   line above at that size. 12.5px / 0.07em reads as quiet structure instead. */
.label {
  margin: 0;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  margin: 0 0 34px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--stroke);
}
.section-head h2 {
  margin: 10px 0 0;
  font-size: clamp(26px, 3.1vw, 38px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.018em;
  color: var(--ink);
  max-width: 17ch;
}
.section-head > p {
  margin: 0 0 4px;
  font-size: 15px;
  color: var(--ink-mute);
  max-width: 40ch;
  text-align: right;
}

.prose { max-width: 62ch; }
.prose p { margin: 0 0 18px; font-size: 16.5px; line-height: 1.68; color: var(--ink-soft); text-wrap: pretty; }
.prose p:last-child { margin-bottom: 0; }
.prose strong { color: var(--ink); font-weight: 600; }

/* one honest caveat, left rule, no box */
.note {
  margin: 26px 0 0;
  padding: 2px 0 2px 20px;
  border-left: 2px solid var(--accent-lift);
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-soft);
  max-width: 66ch;
}
.note strong { color: var(--ink); font-weight: 600; }

/* links inside running text — accent, hairline underline, never the default.
   `.u-link` is the same link wherever it sits. Until 2026-09-25 it had no
   rule of its own and showed the browser's blue in sixteen places across
   the three pages: both "sec-more" links, the /usluge/ lede and price
   facts, and the phone and e-mail in the footer. The accent measures 6.08:1
   on --ground and 5.44:1 on the footer's --ground-sink. The footer's nav
   links keep their quieter look: `.foot-links a` outranks `.u-link`. */
.prose a, .note a, .faq-a a, .loc-card a, .u-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-lift);
}
.prose a:hover, .note a:hover, .faq-a a:hover, .loc-card a:hover, .u-link:hover { border-bottom-color: var(--accent); }


/* ============ PAGE SHELL ============ */
.app { position: relative; z-index: 1; }
.page {
  position: relative;
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.page > section { padding-top: var(--section-gap); }


/* ============ HERO ============
   Rebuilt 2026-09-22 (second pass). The two-column arch-window hero let the
   image sit politely in a frame and never dominate; the footage now runs
   full-bleed and the text sits on top of it in an opaque panel.
   Same full-bleed mechanics as .site-foot and .plan, and safe for the same
   reason — `html { overflow-x: clip }` holds the 50vw/50% scrollbar overshoot
   (trap 18). */
/* The horizontal inset is PADDING on the section, not a margin on the panel.
   A margin of calc(50vw - 50%) on .hero-panel resolves its 50% against
   .hero-video, which is now 100vw wide, so it computes to zero and the
   headline runs off the left edge. As padding here, the 50% resolves against
   .page's content box — the same reason the .site-foot pattern works.
   .hero-media stays full-bleed regardless: an absolutely positioned child is
   laid out against the PADDING box, which spans the padding too. */
.page > .hero-video {
  position: relative;
  margin: 0 calc(50% - 50vw);
  padding: 0 calc(50vw - 50%);
  min-height: clamp(460px, 62vw, 660px);
  display: grid;
  align-items: end;
  isolation: isolate;
}

.hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero-vid,
.hero-media::after { position: absolute; inset: 0; }
.hero-vid {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  display: block;
}
/* The footage is cooler than the page — blue gloves, clinical light. The same
   .ph grade every photograph on this site carries pulls it back onto the
   palette; without it the hero is the one element that does not belong. */
.hero-media::after {
  content: "";
  background: linear-gradient(
    100deg,
    oklch(0.963 0.011 85 / 0.92) 0%,
    oklch(0.963 0.011 85 / 0.72) 34%,
    oklch(0.963 0.011 85 / 0.10) 62%,
    oklch(0.46 0.10 var(--accent-hue) / 0.10) 100%);
  pointer-events: none;
  z-index: 1;
}

/* The panel. Text never sits directly on moving footage: contrast against a
   video cannot be measured, and every ink level here is measured. On
   --ground-lift the h1 keeps 15.69:1. */
/* Pacing loosened 2026-09-23. sigmadent.rs — the practice this concept turned
   out to share a position AND a typeface with — gets most of its calm from air
   rather than from anything it says, and this panel was the densest thing on
   the page: five elements stacked at 20-32px apart inside 28px of padding.
   Every gap below went up by roughly a quarter. No element changed size; the
   page just stopped being in a hurry. This is also where the music idea landed
   instead — calm is bought with rhythm, not with a loop nobody asked to hear. */
.hero-panel {
  position: relative;
  z-index: 2;
  min-width: 0;
  max-width: 640px;
  margin: clamp(56px, 9vw, 96px) 0 clamp(28px, 4vw, 44px);
  padding: clamp(34px, 4.2vw, 52px) clamp(28px, 3.4vw, 44px) clamp(32px, 3.6vw, 44px);
  background: var(--ground-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}

.hero-text { min-width: 0; }
.hero .cta-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 40px; }

/* Open-now state. Written by JS from the published hours in data-hours; the
   markup ships with the plain sentence so it is never empty. */
.hours-now {
  display: flex; align-items: center; gap: 9px;
  margin: 32px 0 0;
  font-size: 14px;
  color: var(--ink-mute);
}
.hours-now::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ink-mute);
  flex-shrink: 0;
}
.hours-now.is-open::before { background: var(--accent); }
.hours-now.is-open .hours-text { color: var(--ink); }
.hours-now .hours-state { font-weight: 600; color: var(--ink); }

/* --- the set-piece: the arch --- */
.arch { margin: 0; min-width: 0; }
.arch-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 5 / 4.4;
  border: 1px solid var(--stroke);
  border-radius: var(--r-arch);            /* THE MOTIF at its largest */
  background:
    radial-gradient(ellipse 70% 55% at 50% 78%, oklch(0.955 0.020 var(--accent-hue) / 0.7), transparent 70%),
    var(--ground-lift);
  overflow: hidden;
}
.arch-frame::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.7), inset 0 -40px 60px -50px rgba(24, 34, 28, 0.4);
  pointer-events: none;
}
/* The JS owns the bitmap and sets it from the CSS box at devicePixelRatio —
   never put width/height attributes on this element. */
.arch-canvas { display: block; width: 100%; height: 100%; }
.arch-cap {
  margin: 14px 0 0;
  text-align: center;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--ink-mute);
  min-height: 1.6em;
}
.arch-cap b { color: var(--ink); font-weight: 600; }

/* ---- the motif carrying the hero photograph ------------------------------
   .arch-frame already owns ::after for its inset highlight, and .ph owns
   ::after for the accent wash. Putting both classes on one element means the
   later rule silently replaces the earlier one and the frame loses its edge —
   so this is its own class and the wash goes on ::before instead. The filter
   is the same grade as .ph so the hero photo belongs to the same set. */
.arch-frame-photo > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 56%;
  filter: saturate(0.72) brightness(1.03) contrast(1.02);
}
.arch-frame-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: oklch(0.46 0.10 var(--accent-hue) / 0.09);
  mix-blend-mode: multiply;
  pointer-events: none;
}
.photo-cap {
  margin: 14px 0 0;
  text-align: center;
  font-size: 12.5px;
  letter-spacing: 0.02em;
  color: var(--ink-mute);
}

/* ---- the arch diagram, now the educator ----------------------------------
   Widened 2026-09-22: the arch sits beside a panel that explains the hovered
   tooth, so the figure is no longer a 520px column. */
.arch-diagram {
  margin: var(--section-gap) auto 0;
  max-width: 980px;
}
.arch-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 3.4vw, 48px);
  align-items: center;
}

.tooth-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* A fixed floor stops the whole figure jumping as cards of different
     lengths replace each other — the arch would shift under the cursor. */
  min-height: 300px;
  padding: 26px 26px 20px;
  background: var(--ground-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}
.tooth-card-idle h3 {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: 600;
  color: var(--ink);
}
.tooth-card-idle p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }
.tooth-kicker { margin: 0 0 6px; font-size: 13px; color: var(--accent); }

.tooth-id {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0 0 3px;
}
.tooth-id b {
  font-family: var(--font-display);
  font-size: clamp(30px, 3.6vw, 42px);
  font-weight: 600;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.tooth-id span {
  font-family: var(--font-display);
  font-size: clamp(17px, 1.8vw, 21px);
  font-weight: 600;
  color: var(--ink);
}
.tooth-where { margin: 0 0 18px; font-size: 13.5px; color: var(--ink-mute); }

.tooth-card dl { margin: 0; display: grid; gap: 15px; }
.tooth-card dt {
  margin-bottom: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-mute);
}
.tooth-card dd { margin: 0; font-size: 14.5px; line-height: 1.62; color: var(--ink); }

.tooth-disclaim {
  margin: auto 0 0;
  padding-top: 16px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-mute);
}
.tooth-card-body[hidden] { display: none; }

.tooth-picks { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.tooth-pick {
  min-height: 44px;
  padding: 10px 16px;
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  cursor: pointer;
  transition: border-color var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.tooth-pick:hover { border-color: var(--accent-lift); color: var(--ink); }
.tooth-pick.is-on { border-color: var(--accent); color: var(--accent); }


/* ============ PROCESS FLOW ============
   Real time anchors, never 01–04. The labels answer "how long does this take"
   at the same time as they order the steps. */
.flow {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px;
}
.flow-step { position: relative; padding-top: 34px; }
.flow-step::before {
  content: "";
  position: absolute; top: 5px; left: -14px; right: -14px;
  height: 1px;
  background: var(--stroke);
}
.flow-step:first-child::before { left: 5px; }
.flow-step:last-child::before { right: 50%; }
.flow-step::after {
  content: "";
  position: absolute; top: 0; left: 0;
  width: 11px; height: 11px;
  background: var(--accent);
  border-radius: 999px 999px 1px 1px;      /* the arch, at node size */
}
/* Real time anchors — POZIV, TERMIN · 30 MIN, ISTI DAN, ZA 6 MESECI. These
   earn their caps: they are the spine of the sequence, not a label above a
   heading. Tracking down from 0.12em and size up from 11.5px for the same
   diacritic reason as .label. */
.flow-time {
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent);
}
.flow-step h3 {
  margin: 10px 0 8px;
  font-size: 19px; font-weight: 600; letter-spacing: -0.012em;
  color: var(--ink);
}
.flow-step p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }


/* ============ PHOTOGRAPHY ============
   Three photographs, from three different shoots, on a page whose whole palette
   is one warm ground and one green. Left alone they read as three stock images;
   the shared treatment below is what makes them read as one set.

   It is deliberately light — pull the saturation down, lift the brightness a
   touch, lay a 9% wash of the accent over the top in multiply. Enough to seat
   them in the palette, not enough to look like a filter: a heavy grade on a
   clinic photo reads as hiding a bad photograph.

   NO IDENTIFIABLE FACES anywhere on this site. A CC0 licence covers copyright,
   not the person in the frame, and a fictional practice must not appear to
   employ a real one. See ../../docs/design-direction.md. */
.ph { position: relative; margin: 0; overflow: hidden; background: var(--ground-sink); }
.ph img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The grade itself, named for BOTH shapes it has to reach.

   `.ph img` alone cannot match the hero, for two reasons at once: the hero is a
   <video>, and it carries .ph on the element itself rather than on a wrapper.
   So the largest, first, most-looked-at image on the page computed
   `filter: none` while every photograph under it was graded — and it looked
   handled, because .ph was right there in its class list and .hero-media::after
   was laying the porcelain wash over it. The wash was doing half the job and
   covering for the half that was missing.

   Found 2026-09-23 by reading computed style on a served page. If a third
   shape ever appears, add it here rather than duplicating the values. */
.ph img,
.ph video,
video.ph {
  filter: saturate(0.72) brightness(1.03) contrast(1.02);
}
.ph::after {
  content: "";
  position: absolute; inset: 0;
  background: oklch(0.46 0.10 var(--accent-hue) / 0.09);
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* the wide band: full viewport width, same technique as the footer */
/* .photo-band was removed 2026-09-22 — the full-bleed slot now holds the arch
   diagram, and the room photograph moved up into the hero. Kept out rather
   than left behind: unused CSS is the drift a stylesheet accumulates. The
   full-bleed technique itself survives on .site-foot if it is ever needed. */

/* the motif, carrying an image. Used once. */
.photo-arch {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--stroke);
  border-radius: var(--r-arch);
}
.photo-arch img { object-position: 50% 58%; }

.photo-plain {
  aspect-ratio: 3 / 2;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}

/* the section opener: a wide strip, cropped hard. Used above the team, where
   the page needs a person present without claiming who that person is. */
.photo-strip {
  /* was clamp(150px, 17vw, 232px) — a 5:1 letterbox out of a 3:2 original,
     which cropped the cast and most of the hand out of frame. Raised
     2026-09-22 so the subject survives; still a strip, not a picture. */
  height: clamp(190px, 22vw, 300px);
  margin-bottom: 40px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}
.photo-strip img { object-position: 50% 46%; }

/* a figure above a panel — the same column shape in two sections */
.fear-side, .loc-side { display: grid; gap: 24px; align-content: start; min-width: 0; }


/* ============ PLAN — the specimen ============
   The page's one loud object, and the only place the boldness is spent. It is
   a document, so it is set like one and not like a UI card: the arch on the
   top corners (the motif, fourth appearance), a rule under the header, tabular
   figures, and nothing a printed plan would not have. No shadow — the sheet
   sits on --ground-lift inside a hairline, which is how every other surface on
   this page is built.
   The three states are a dot and a word, never a coloured pill per row: pills
   would turn a piece of paper into a dashboard. Added 2026-09-22. */
/* The band. The sheet is --ground-lift and the page is --ground, and those two
   are 1.06:1 apart — on its own the sheet read as a faintly outlined rectangle,
   which is not what the page's one loud object should do. Dropping the section
   to --ground-sink gives the paper something to sit on and costs no shadow.
   Same full-bleed as .site-foot, and it is safe for the same reason: the
   `50vw` vs `50%` scrollbar overshoot (trap 18) is already held by
   `html { overflow-x: clip }` at the top of this file.
   `.page > .plan` and not `.plan`, because `.page > section` sets padding-top
   and would otherwise win on specificity. */
.page > .plan {
  margin: var(--section-gap) calc(50% - 50vw) 0;
  padding: var(--section-gap) calc(50vw - 50%);
  background: var(--ground-sink);
  border-top: 1px solid var(--stroke);
  border-bottom: 1px solid var(--stroke);
}

.plan-wrap {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: 44px;
  align-items: start;
}

/* The sheet does NOT take --r-arch. Tried it: at ~700px wide the 999px radius
   stops being an arch and becomes a wide shallow dome — the motif distorted by
   the aspect it was applied to, eating 60px at the top of the object the whole
   section exists for. The arch already appears on the mark, the favicon, the
   hero frame, the diagram and the team plates; a sixth, stretched, weakens the
   five that work. This is paper, so it gets the structural radius. */
.plan-sheet {
  background: var(--ground-lift);
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  padding: 38px 40px 32px;
  min-width: 0;
}

.plan-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--stroke);
}

/* Sentence case, not caps. A tracked-caps kicker here would have been the
   tell the 2026-09-22 pass spent the morning removing. */
.plan-kicker {
  margin: 0 0 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
}

.plan-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(22px, 2.2vw, 30px);
  font-weight: 600;
  line-height: 1.08;
  color: var(--ink);
}

.plan-meta { display: grid; gap: 9px; margin: 0; text-align: right; }
.plan-meta > div { display: grid; gap: 2px; }
.plan-meta dt { font-size: 12.5px; color: var(--ink-mute); }
.plan-meta dd { margin: 0; font-size: 14px; color: var(--ink-soft); }

.plan-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 4px;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.plan-table th,
.plan-table td {
  padding: 13px 10px;
  text-align: left;
  vertical-align: baseline;
  border-bottom: 1px solid var(--stroke-quiet);
}
.plan-table thead th {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-mute);
  border-bottom-color: var(--stroke);
}
.plan-table th:first-child,
.plan-table td:first-child { padding-left: 0; }
.plan-table tbody td { color: var(--ink); }
.plan-table .plan-num { text-align: right; padding-right: 0; }
.plan-tooth { width: 3.6em; color: var(--ink-mute); }

.plan-table tfoot th,
.plan-table tfoot .plan-num {
  padding-top: 19px;
  border-bottom: 0;
}
.plan-table tfoot th {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-soft);
}
.plan-table tfoot .plan-num {
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
}

.plan-when {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-soft);
  white-space: nowrap;
}
.plan-when::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  transform: translateY(-1px);
}
.plan-when.now::before   { background: var(--accent); }
.plan-when.wait::before  { background: var(--accent-lift); }
.plan-when.watch::before { box-shadow: inset 0 0 0 1px var(--stroke-field); }

.plan-foot {
  margin: 24px 0 0;
  font-size: 14px;
  line-height: 1.62;
  color: var(--ink-soft);
}
.plan-foot em { font-style: italic; color: var(--ink); }

.plan-legend { padding-top: 10px; min-width: 0; }
.plan-legend-lead {
  margin: 0 0 22px;
  font-family: var(--font-display);
  font-size: 19px;
  line-height: 1.3;
  color: var(--ink);
}
.plan-legend dl { margin: 0; display: grid; gap: 19px; }
.plan-legend dt { margin-bottom: 6px; }
.plan-legend dd {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-soft);
}


/* ============ SERVICES — editorial list ============
   The replacement for the icon-card grid. No arrow: these rows do not lead
   anywhere on a single page, and an arrow that does nothing is a lie. The
   third column carries the number a visitor actually came for. */
.svc-list { border-top: 1px solid var(--stroke); }
.svc-row {
  display: grid;
  grid-template-columns: minmax(180px, 27%) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px 40px;
  padding: 26px 6px 24px;
  border-bottom: 1px solid var(--stroke-quiet);
  transition: background var(--t-micro) var(--ease);
}
.svc-row:hover { background: var(--wash); }
.svc-name {
  margin: 0;
  font-size: clamp(20px, 2.3vw, 26px);
  font-weight: 600; line-height: 1.15; letter-spacing: -0.018em;
  color: var(--ink);
}
.svc-desc { margin: 0; font-size: 15px; line-height: 1.58; color: var(--ink-soft); max-width: 56ch; }
.svc-from {
  margin: 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
  white-space: nowrap;
}


/* ============ FEAR — the section every competitor leaves out ============ */
.fear {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.fear-body h2 {
  margin: 12px 0 26px;
  font-size: clamp(30px, 4.4vw, 52px);
  font-weight: 600; line-height: 1.05; letter-spacing: -0.022em;
  color: var(--ink);
}
.fear-aside {
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground-lift);
  padding: 26px 28px 24px;
}
.fear-aside h3 {
  margin: 0 0 4px;
  font-size: 20px; font-weight: 600; letter-spacing: -0.012em;
  color: var(--ink);
}
.spec-rows { margin: 0; }
.spec-rows > div {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--stroke-quiet);
  align-items: baseline;
}
.spec-rows dt {
  margin: 0;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-mute);
}
.spec-rows dd { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ink-soft); }
.aside-foot {
  margin: 18px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--stroke-quiet);
  font-size: 14px;
  color: var(--ink-mute);
}


/* ============ PRICING ============ */
.price-group { margin-top: 44px; }
.price-group:first-of-type { margin-top: 0; }
.price-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0 4px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--stroke-field);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink);
}
.price-head span { color: var(--ink-mute); font-weight: 500; }
.price-row {
  display: grid;
  grid-template-columns: minmax(190px, 28%) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 8px 36px;
  padding: 18px 4px;
  border-bottom: 1px solid var(--stroke-quiet);
}
.price-name {
  margin: 0;
  font-size: 17.5px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--ink);
}
.price-desc { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ink-soft); max-width: 54ch; }
.price-fig {
  margin: 0;
  font-size: 16px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
  text-align: right;
}


/* ============ TEAM ============
   No photographs anywhere on this build: a fictional practice may not wear a
   real person's face. The plates are monograms in the arch, and they are meant
   to read as a deliberate object, not as a missing image. On a client build
   these become photographs — see ../../asset-requests.md. */
.team-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 44px);
}
.member h3 {
  margin: 20px 0 4px;
  font-size: 21px; font-weight: 600; letter-spacing: -0.012em;
  color: var(--ink);
}
.member-role { margin: 0 0 10px; font-size: 13px; font-weight: 600; letter-spacing: 0.04em; color: var(--accent); }
.member-line { margin: 0; font-size: 14.5px; line-height: 1.58; color: var(--ink-soft); }
.plate {
  position: relative;
  display: flex;
  align-items: center; justify-content: center;
  width: min(100%, 208px);
  aspect-ratio: 4 / 5;
  border: 1px solid var(--stroke);
  border-radius: var(--r-arch);
  background:
    radial-gradient(ellipse 80% 60% at 50% 100%, oklch(0.95 0.024 var(--accent-hue) / 0.8), transparent 72%),
    var(--ground-sink);
}
/* ---- plates carrying a photograph, 2026-09-22 ---------------------------
   The monogram plates were the honest answer while there was no photography.
   Now they hold portraits — but the people in them are NOT the people named
   under them, so every plate carries a visible marker saying the photograph
   is illustrative. That marker is what keeps this inside rule 3: the fiction
   is allowed only while it is labelled, and a stock face under an invented
   name in a regulated profession is the one thing this sector must not do.
   Do not remove .plate-tag to tidy up the design. */
.plate.has-photo { overflow: hidden; background: var(--ground-sink); }
.plate.has-photo > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
  display: block;
  /* the same grade every other photograph on the page carries, so three
     portraits from three different shoots still read as one set */
  filter: saturate(0.72) brightness(1.03) contrast(1.02);
}
/* the inner-arch flourish belongs to the empty plate only */
.plate.has-photo::after { content: none; }

/* `.plate .plate-tag` and not `.plate-tag`: the monogram rule below is
   `.plate span`, which also matches this span and beats a single class — the
   marker rendered in 40px display serif across the whole portrait. */
.plate .plate-tag {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 6px 10px 7px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: 0;
  text-align: center;
  color: var(--ink-soft);
  background: oklch(0.985 0.008 85 / 0.93);
  border-top: 1px solid var(--stroke);
}

/* the mark's inner arch, repeated at plate scale */
.plate::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 34%; height: 30%;
  transform: translateX(-50%);
  border: 1px solid var(--stroke);
  border-bottom: 0;
  border-radius: 999px 999px 0 0;
}
.plate span {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--accent);
  transform: translateY(-8%);
}


/* ============ FAQ ============
   Plain markup, not <details>. The answers stay in the DOM and visible: for
   anyone with JS off, for crawlers that quote the page, and because hiding six
   answers behind six clicks is worse than a scroll. */
.faq-list { display: grid; max-width: 82ch; }
.faq-item { padding: 24px 0; border-bottom: 1px solid var(--stroke-quiet); }
.faq-item:first-child { border-top: 1px solid var(--stroke); }
.faq-q {
  margin: 0 0 10px;
  font-size: clamp(18px, 2vw, 21px);
  font-weight: 600; letter-spacing: -0.014em;
  color: var(--ink);
}
.faq-a { margin: 0; font-size: 15.5px; line-height: 1.68; color: var(--ink-soft); }


/* ============ LOCATION ============ */
.loc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}
.loc-main { min-width: 0; }

/* THE MAP — drawn, not embedded. A Google Maps iframe is blocked by the CSP,
   and the address is fictional, so a real map would point at somebody's actual
   building. This shows the shape of the approach with no street names; the card
   beside it carries the facts. */
.map {
  margin: 0 0 36px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground-lift);
  overflow: hidden;
}
.map svg { display: block; width: 100%; height: auto; }
.map-blocks rect { fill: var(--ground-sink); }
.map-here {
  fill: oklch(0.46 0.10 var(--accent-hue) / 0.12);
  stroke: var(--accent-lift);
  stroke-width: 1;
}
.map-yard { fill: oklch(0.46 0.10 var(--accent-hue) / 0.06); }
.map-tram {
  stroke: var(--ink-mute);
  stroke-width: 1.5;
  stroke-dasharray: 9 7;
  opacity: 0.5;
}
.map-pin path { fill: var(--accent); }
.map-pin .map-pin-door { fill: var(--ground-lift); }
/* Caps on a schematic map is cartographic convention, not an eyebrow label, so
   it stays. Tracking eased for the Š in DVORIŠTA. The 10px is in a 420-wide
   viewBox that renders near 500px, so the effective size is ~12px. */
.map-label {
  font-family: var(--font-sans);
  font-size: 10px; font-weight: 600; letter-spacing: 0.08em;
  fill: var(--ink-mute);
}
.map-label-here { fill: var(--accent); }

.hours { width: 100%; border-collapse: collapse; }
.hours caption {
  text-align: left;
  padding-bottom: 12px;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-mute);
}
.hours th, .hours td {
  padding: 15px 2px;
  border-bottom: 1px solid var(--stroke-quiet);
  font-size: 15.5px;
  text-align: left;
}
.hours tr:first-child th, .hours tr:first-child td { border-top: 1px solid var(--stroke); }
.hours th { font-weight: 500; color: var(--ink-soft); }
.hours td { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--ink); }

.loc-card {
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground-lift);
  padding: 26px 28px;
}
.loc-card h3 { margin: 0 0 14px; font-size: 20px; font-weight: 600; letter-spacing: -0.012em; }
.loc-card p {
  margin: 0;
  padding: 13px 0;
  border-top: 1px solid var(--stroke-quiet);
  font-size: 15px; line-height: 1.6;
  color: var(--ink-soft);
}
.loc-card p:last-child { padding-bottom: 0; }


/* ============ CONTACT ============ */
.contact {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.contact h2 {
  margin: 12px 0 18px;
  font-size: clamp(28px, 3.6vw, 42px);
  font-weight: 600; line-height: 1.08; letter-spacing: -0.02em;
  color: var(--ink);
  max-width: 14ch;
}
.channels { margin-top: 34px; border-top: 1px solid var(--stroke); }
.channel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px 4px;
  border-bottom: 1px solid var(--stroke-quiet);
  color: var(--ink);
  transition: padding var(--t-micro) var(--ease), background var(--t-micro) var(--ease);
}
a.channel:hover { background: var(--wash); padding-left: 12px; }
a.channel:hover strong { color: var(--accent); }
.channel-label {
  font-size: 12px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-mute);
}
.channel-value {
  font-family: var(--font-display);
  font-size: clamp(21px, 2.4vw, 27px);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  transition: color var(--t-micro) var(--ease);
}
.channel-value:hover { color: var(--accent); }
.channel-apps { display: flex; gap: 8px; margin-top: 12px; }
.channel strong {
  font-family: var(--font-display);
  font-size: clamp(21px, 2.4vw, 27px);
  font-weight: 500;
  letter-spacing: -0.01em;
  transition: color var(--t-micro) var(--ease);
}

.contact-form {
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground-lift);
  padding: 28px 30px 26px;
}
.field { margin-bottom: 18px; }
.field label {
  display: block;
  margin-bottom: 7px;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-mute);
}
.field input, .field textarea {
  width: 100%;
  padding: 12px 14px;
  font-family: inherit;
  font-size: 15.5px;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--stroke-field);
  border-radius: var(--r-structural);
  transition: border-color var(--t-micro) var(--ease), background var(--t-micro) var(--ease);
}
.field textarea { resize: vertical; min-height: 108px; line-height: 1.55; }

/* Two shots of the place, side by side. The section answers "what am I
   walking into" and one photograph only ever answered half of it. */
.loc-shots { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.loc-shots .photo-plain { margin: 0; }

/* The services figure: a 3:4 portrait beside its caption. The only photograph
   on the page that makes a point rather than setting a scene, so it gets to
   say it in words next to it rather than float unexplained.

   The figure is a LAYOUT box and carries no grade. .ph goes one level down, on
   .svc-shot, because .ph is a picture wrapper: it paints --ground-sink and
   absolutely positions a 9% accent wash over its whole box. On the figure that
   wash covered the figcaption too, so the caption was not rendering at the
   --ink-soft 6.92:1 the contrast table reports for it. Every other photograph
   here already gets this right (.photo-arch, .photo-strip, .photo-plain are
   each a .ph wrapping one <img> and nothing else); this block was the one that
   drifted. */
.svc-figure {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 40px);
  align-items: center;
  margin: 0 0 40px;
  padding-bottom: 34px;
  border-bottom: 1px solid var(--stroke-quiet);
}
.svc-shot {
  aspect-ratio: 3 / 4;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}
.svc-figure figcaption {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-soft);
  max-width: 54ch;
}

.loc-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 12px; }
.loc-note { margin: 0; font-size: 13px; line-height: 1.55; color: var(--ink-mute); }

/* ---- the guided inquiry, 2026-09-22 --------------------------------------
   Selects are styled to match the inputs rather than left at the OS widget:
   a native Windows select next to these fields is the same category of
   un-designed surface as an unthemed ::selection. */
.field select {
  width: 100%;
  padding: 12px 40px 12px 14px;
  font-family: inherit;
  font-size: 15.5px;
  color: var(--ink);
  background-color: var(--ground);
  border: 1px solid var(--stroke-field);
  border-radius: var(--r-structural);
  appearance: none;
  /* the chevron is drawn, not a glyph — Unicode dingbats as icons is a tell */
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%, currentColor calc(50% + 1.2px), transparent calc(50% + 1.2px)),
    linear-gradient(-45deg, transparent 50%, currentColor 50%, currentColor calc(50% + 1.2px), transparent calc(50% + 1.2px));
  background-position: calc(100% - 20px) 55%, calc(100% - 14px) 55%;
  background-size: 6px 6px;
  background-repeat: no-repeat;
}
.field select:focus { border-color: var(--accent); background-color: var(--ground-lift); }

/* ---- the hero trust row, 2026-09-22 --------------------------------------
   Three checkable facts, not badges. Hairline-separated so it reads as part of
   the panel rather than as a widget bolted onto it. */
/* Three columns, not a wrapping flex row. As flex, the three items broke 2 + 1
   inside the 640px panel at 1440 — which looks like a bug, not a layout. A grid
   holds the row at every width the panel has, and stacks at 560. */
.trust-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 26px;
  margin: 28px 0 0;
  padding: 24px 0 0;
  border-top: 1px solid var(--stroke);
  list-style: none;
}
.trust-row li { display: grid; gap: 1px; min-width: 0; }
.trust-row b {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.trust-row span { font-size: 12.5px; line-height: 1.4; color: var(--ink-mute); }

/* ---- the credentials slot ------------------------------------------------
   A visible absence. Dashed, because a solid card reads as content and this is
   deliberately not content — it is the shape of what is missing. */
/* The withheld proof. Three slots as of 2026-09-23, was one.

   The dashed border is the whole device: it reads as a space reserved rather
   than a space forgotten, and it is the only dashed stroke on the page, so it
   cannot be mistaken for a component. Nothing in here ever gets a badge, a
   star or a photograph — the moment it does, it stops being an empty slot and
   starts being a claim. */
.creds {
  margin-top: clamp(40px, 5vw, 64px);
  padding: clamp(24px, 3vw, 34px);
  border: 1px dashed var(--stroke-field);
  border-radius: var(--r-structural);
  background: transparent;
}
.creds-lead { max-width: 62ch; margin-bottom: clamp(22px, 2.6vw, 30px); }
.creds h3 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: clamp(17px, 1.9vw, 21px);
  font-weight: 600;
  color: var(--ink);
}
.creds h4 {
  margin: 0 0 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}
.creds-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 34px);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* A hairline between the slots, not a box around each: three boxes inside a
   dashed box is two frames too many. */
.creds-list > li + li {
  padding-left: clamp(20px, 2.6vw, 34px);
  border-left: 1px solid var(--stroke-quiet);
}
.creds p { margin: 0; font-size: 14.5px; line-height: 1.62; color: var(--ink-soft); }
.creds-list p + p { margin-top: 10px; }
.creds-note { font-size: 13.5px; color: var(--ink-mute); }
.creds-note b { color: var(--ink-soft); font-weight: 600; }

/* ---- drawn icons, 2026-09-22 ---------------------------------------------
   One sprite of <symbol>s at the top of <body>, pulled in with <use>. They
   inherit currentColor so they carry the accent on hover with the label,
   instead of being a second colour system. */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  fill: currentColor;
  /* optical baseline: a solid glyph beside text sits a touch high */
  transform: translateY(0.085em);
}
.has-ico { display: inline-flex; align-items: center; gap: 0.5em; }
.channel-value.has-ico { gap: 0.42em; }
.channel-value .ico { color: var(--accent); }
.action-btn.has-ico { justify-content: center; gap: 0.42em; }

/* ---- the inquiry dialog ---------------------------------------------------
   Native <dialog>: showModal() brings the focus trap, Escape, an inert
   background and ::backdrop, all of which hand-rolled overlays get wrong. */
.contact-open { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin: 30px 0 0; }
.contact-open-note { font-size: 13.5px; line-height: 1.5; color: var(--ink-mute); max-width: 34ch; }

.inq-modal {
  width: min(560px, calc(100vw - 32px));
  max-height: min(86vh, 760px);
  padding: 0;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground-lift);
  color: var(--ink);
  overflow: auto;
  overscroll-behavior: contain;
}
.inq-modal::backdrop { background: oklch(0.24 0.018 156 / 0.46); }

.inq-modal-head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px 16px;
  background: var(--ground-lift);
  border-bottom: 1px solid var(--stroke);
}
.inq-modal-head h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(19px, 2.2vw, 23px);
  font-weight: 600;
  color: var(--ink);
}
/* The close mark is DRAWN, not a Unicode multiplication sign or an emoji —
   glyph-as-icon is a tell the detector checks for. */
.inq-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.inq-close:hover { border-color: var(--accent); color: var(--accent); }
.inq-close svg { width: 17px; height: 17px; stroke: currentColor; stroke-width: 1.6; fill: none; stroke-linecap: round; }

/* inside the dialog the form is no longer its own bordered card */
.inq-modal .contact-form { border: 0; border-radius: 0; background: transparent; padding: 20px 22px 24px; }

.inq-rail {
  display: flex;
  gap: 8px;
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
}
.inq-dot {
  flex: 1;
  padding-top: 9px;
  border-top: 2px solid var(--stroke);
  font-size: 12.5px;
  color: var(--ink-mute);
  transition: border-color var(--t-micro) var(--ease), color var(--t-micro) var(--ease);
}
.inq-dot.is-on { border-top-color: var(--accent); color: var(--accent); }

.inq-step { border: 0; margin: 0; padding: 0; min-width: 0; }
.inq-step legend {
  padding: 0;
  margin-bottom: 18px;
  font-family: var(--font-display);
  font-size: clamp(19px, 1.9vw, 23px);
  font-weight: 600;
  color: var(--ink);
}
.inq-step legend:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.opt-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.opt {
  position: relative;
  display: block;
  padding: 14px 16px;
  min-height: 44px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
  background: var(--ground);
  cursor: pointer;
  transition: border-color var(--t-micro) var(--ease), background var(--t-micro) var(--ease);
}
.opt:hover { border-color: var(--accent-lift); }
.opt input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.opt-t { display: block; font-weight: 600; font-size: 15px; color: var(--ink); }
.opt-s { display: block; margin-top: 3px; font-size: 13px; color: var(--ink-mute); font-weight: 400; letter-spacing: 0; text-transform: none; }
.opt:has(input:checked) { border-color: var(--accent); background: var(--ground-lift); box-shadow: inset 0 0 0 1px var(--accent); }
.opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.inq-nav { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 24px; }
/* `.btn` sets an explicit display, which beats the UA's [hidden]{display:none}
   — so all three nav buttons showed at once. Specificity, not !important.
   The rail and the button row are flex for the same reason, and both are
   hidden once the inquiry is sent (initInquiry in app.js). */
.inq-rail[hidden], .inq-nav[hidden], .inq-nav [hidden], .inq-step[hidden] { display: none; }
.inq-recap {
  margin: 20px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--stroke-quiet);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.inq-recap:empty { display: none; }
.inq-recap strong { display: block; margin-bottom: 8px; color: var(--ink); font-weight: 600; }
.recap-row { display: flex; gap: 10px; padding: 3px 0; }
.recap-row em {
  flex: none;
  width: 78px;
  font-style: normal;
  color: var(--ink-mute);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-mute); }
.field.focused label { color: var(--accent); }
.field input:focus, .field textarea:focus { border-color: var(--accent); background: var(--ground-lift); }
.field.invalid input, .field.invalid textarea { border-color: #a3232a; }
.field-error { margin: 7px 0 0; font-size: 13px; color: #8e1f25; }
.field.hp { position: absolute; left: -9999px; }

.contact-form .btn { width: 100%; }
.form-note { margin: 14px 0 0; font-size: 13px; line-height: 1.55; color: var(--ink-mute); }
.form-done {
  margin: 14px 0 0;
  padding: 12px 14px;
  border-left: 2px solid var(--accent);
  background: var(--wash);
  font-size: 14.5px;
  color: var(--ink);
}


/* ============ FOOTER ============
   The band runs the full viewport width while its content stays on the page
   grid: negative inline margins push the box out to the viewport edges and the
   matching padding puts the content back. `overflow-x: clip` on html and body
   is what makes it safe.

   Tried and rejected: an absolutely positioned ::before at `inset: 0 -50vw`
   with `z-index: -1`. It computed correctly and painted nothing — the band was
   simply invisible in the browser. Do not reintroduce it. */
.site-foot {
  position: relative;
  margin: var(--section-gap) calc(50% - 50vw) 0;
  padding: 44px calc(50vw - 50%) 36px;
  background: var(--ground-sink);
  border-top: 1px solid var(--stroke);
}
.foot-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) auto;
  gap: 32px;
  align-items: start;
}
.foot-brand { display: flex; gap: 12px; align-items: flex-start; }
.foot-brand strong {
  display: block;
  font-family: var(--font-display);
  font-size: 18px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--ink);
}
.foot-brand em { display: block; margin-top: 5px; font-size: 13.5px; color: var(--ink-mute); max-width: 30ch; }
.foot-links { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.foot-links a {
  font-size: 14px;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.foot-links a:hover { color: var(--accent); border-bottom-color: var(--accent-lift); }
.foot-meta { display: flex; flex-direction: column; gap: 6px; text-align: right; font-size: 13px; color: var(--ink-mute); }
.foot-demo {
  margin: 36px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--stroke-quiet);
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-mute);
  max-width: 76ch;
}
.foot-demo a { color: var(--ink-soft); }


/* ==========================================================================
   CONVERSION — the CTA band and the phone action bar
   --------------------------------------------------------------------------
   This page is a lead generator: the job is a call or a booking. Before
   2026-09-22 it asked once in the hero and then not again for ~8,000px.
   ========================================================================== */

.cta-band {
  margin: var(--section-gap) 0 0;
  padding: clamp(28px, 4vw, 44px) clamp(24px, 4vw, 48px);
  border: 1px solid var(--stroke);
  border-radius: var(--r-arch);          /* the motif, once more */
  background:
    radial-gradient(ellipse 80% 120% at 50% 100%, oklch(0.955 0.020 var(--accent-hue) / 0.8), transparent 70%),
    var(--ground-lift);
}
.cta-band-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 56px);
  flex-wrap: wrap;
}
.cta-band-h {
  font-size: clamp(23px, 2.5vw, 31px);
  line-height: 1.22;
  margin: 0;
}
.cta-band-p {
  margin: 10px 0 0;
  max-width: 54ch;
  color: var(--ink-soft);
}
.cta-band-actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* The phone action bar. Hidden on desktop, where the sticky header already
   carries the number — see the 760px breakpoint below, which is also where
   body gains the bottom padding that stops it covering the footer. */
.action-bar { display: none; }

/* ==========================================================================
   MOBILE OVERRIDES — the end of the file, so later wins at equal specificity.
   Breakpoints are named for what breaks, not for a device.
   ========================================================================== */

/* 1080px — the hero's two columns stop having room for a 15ch headline */
@media (max-width: 1080px) {
  .hero { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .arch { max-width: 460px; margin: 0 auto; width: 100%; }
  .fear, .contact { grid-template-columns: minmax(0, 1fr); }
  .fear-side, .contact-form { max-width: 620px; }
  .flow { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px 28px; }
  .flow-step:nth-child(2)::before { right: 5px; }
  .flow-step:nth-child(3)::before { left: 5px; }
  .flow-step:last-child::before { right: 5px; }
}

/* 900px — the section head's right-hand sentence has nowhere left to sit,
   and the three team plates get too narrow for a monogram */
@media (max-width: 900px) {
  :root { --gutter: 28px; }
  .section-head { flex-direction: column; align-items: flex-start; gap: 12px; }
  .section-head > p { text-align: left; max-width: 56ch; }
  .team-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .member:last-child { max-width: 50%; }
  .loc-grid { grid-template-columns: minmax(0, 1fr); }
  .loc-side { max-width: 620px; }
  /* the legend stops being a margin note and becomes what you read next */
  .plan-wrap { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .plan-legend { padding-top: 0; max-width: 620px; }

  /* The hero panel stops being a card on footage and becomes the page again.
     The video keeps a band of its own above it so the people in it stay
     visible; a panel overlaid on a near-portrait viewport leaves the footage
     as two slivers down the sides, which is worse than no video. */
  .page > .hero-video {
    min-height: 0;
    display: block;
    margin-bottom: 8px;
  }
  .hero-media { position: relative; height: clamp(230px, 46vw, 340px); }
  .hero-media::after {
    background: linear-gradient(
      170deg,
      oklch(0.963 0.011 85 / 0.14) 0%,
      oklch(0.963 0.011 85 / 0.50) 76%,
      oklch(0.963 0.011 85 / 0.97) 100%);
  }
  .hero-panel {
    max-width: none;
    margin: 30px 0 0;
    padding: 0;
    border: 0;
    background: transparent;
  }

  /* The educator stacks: arch first, then the panel it explains. */
  .arch-stage { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .arch-diagram { max-width: 560px; }
  .tooth-card { min-height: 0; }

  .svc-figure { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .svc-shot { max-width: 320px; }
  .loc-shots { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  /* Three slots side by side need ~200px each to keep the notes readable.
     Below the 1080 breakpoint they stack, and the hairline moves to the top
     edge so it still separates them. */
  .creds-list { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .creds-list > li + li {
    padding-left: 0;
    padding-top: 20px;
    border-left: 0;
    border-top: 1px solid var(--stroke-quiet);
  }
}

/* 760px — five nav links wrap to a second row on a sticky bar, which is a
   permanent tax on the viewport. Brand and CTA survive, links go. */
@media (max-width: 760px) {
  /* ---- the phone action bar ---------------------------------------------
     This is where the nav pills disappear, so from here down the only way to
     reach the number mid-page was to scroll back to the header. */
  .action-bar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: 1fr 1fr 1.35fr;
    gap: 8px;
    padding: 9px 12px calc(9px + env(safe-area-inset-bottom));
    background: oklch(0.985 0.008 85 / 0.93);
    backdrop-filter: blur(10px);           /* content passes behind it */
    border-top: 1px solid var(--stroke);
  }
  .action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 46px;                      /* over the 44 floor, with room */
    padding: 0 10px;
    border: 1px solid var(--stroke-field);
    border-radius: var(--r-structural);
    font-size: 14px;
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
    background: var(--ground-lift);
  }
  .action-btn-primary {
    background: var(--accent);
    border-color: var(--accent-sink);
    color: #fff;
    border-radius: var(--r-pill);          /* the pill stays the primary action */
  }
  /* So the bar never covers the last line of the footer. */
  body { padding-bottom: 76px; }

  .cta-band-in { display: block; }
  .cta-band-actions { margin-top: 22px; }
  .cta-band-actions .btn { width: 100%; }

  .nav-items { display: none; }
  .nav-inner { justify-content: space-between; }
  .demo-inner { flex-wrap: wrap; gap: 6px 12px; font-size: 12px; }
  .demo-link { margin-left: 0; }
  /* Name and figure share row one; the description spans row two. Without the
     explicit placement the figure is auto-placed AFTER the spanning
     description and lands on a row of its own. */
  .svc-row {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 20px;
  }
  .svc-desc { grid-row: 2; grid-column: 1 / -1; }
  .svc-from { grid-row: 1; grid-column: 2; }
  .price-row { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 20px; }
  .price-desc { grid-row: 2; grid-column: 1 / -1; }
  .price-fig { grid-row: 1; grid-column: 2; }
  .foot-row { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .foot-meta { text-align: left; }

  /* Touch targets. The header phone number is the most-tapped element on the
     site at this width and it measured 39px tall. */
  .nav-inner .btn, .channel-apps .btn { min-height: 44px; }
  .foot-links { gap: 0 22px; }
  .foot-links a { display: inline-flex; align-items: center; min-height: 44px; }
}

/* 560px — a 360px phone keeps 320px of content at this gutter, and nothing
   inside adds a second one */
@media (max-width: 560px) {
  :root { --gutter: 20px; }
  [id] { scroll-margin-top: 80px; }
  .display { max-width: none; }
  /* Three trust claims side by side at 390 would be ~110px each — the second
     line of every one would wrap to three. They stack. */
  .trust-row { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .flow { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .flow-step { padding: 0 0 26px 26px; }
  .flow-step::before {
    top: 6px; bottom: -6px; left: 5px; right: auto;
    width: 1px; height: auto;
  }
  .flow-step:first-child::before, .flow-step:last-child::before { left: 5px; right: auto; }
  .flow-step:last-child::before { bottom: auto; height: 0; }
  .flow-step::after { top: 5px; left: 0; }
  .flow-step h3 { margin-top: 6px; }
  .team-list { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .member:last-child { max-width: none; }
  .fear-aside, .contact-form, .loc-card { padding: 22px 20px; }
  /* the sheet keeps all four columns — a plan that drops its prices on a phone
     is not the artefact this section is about. Padding and type give the room
     instead, and the header stacks so the date does not squeeze the title. */
  .plan-sheet { padding: 30px 22px 26px; }
  .plan-head { flex-direction: column; align-items: flex-start; gap: 14px; }
  .plan-meta { text-align: left; grid-auto-flow: column; gap: 26px; }
  .plan-table { font-size: 14px; }
  .plan-table th, .plan-table td { padding: 11px 7px; }
  .plan-tooth { width: 2.6em; }
  .plan-when { font-size: 13px; gap: 6px; }
  .spec-rows > div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .hero .cta-row .btn { width: 100%; }
}


/* ============ REDUCED MOTION ============
   The arch renders its FINISHED state under this, never a blank frame — the
   JS reads the same query and draws at t = duration. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   SUBPAGES — /usluge/ and /cenovnik/, added 2026-09-23
   ==========================================================================
   The site became multi-page because every one of the nine practices in the
   third competitor pass has real routes and every SVOD nav pill was an anchor.
   A visitor who clicks "Usluge" and gets a scroll has met a landing page, not a
   practice (docs/competitor-set.md).

   These styles are deliberately thin. A subpage that needs its own design
   system is a second site; everything here reuses the home page's tokens,
   type scale and spacing, and adds only the three things a subpage needs that
   a one-pager never did: a breadcrumb, a page title smaller than a hero, and a
   jump list. */

.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: clamp(22px, 3vw, 34px) 0 0;
  font-size: 13.5px;
  color: var(--ink-mute);
}
.crumbs a { color: var(--ink-mute); text-decoration: none; border-bottom: 1px solid var(--stroke); }
.crumbs a:hover { color: var(--accent); border-bottom-color: currentColor; }
.crumbs [aria-current] { color: var(--ink-soft); }

.page-head {
  max-width: 62ch;
  margin: clamp(18px, 2.4vw, 26px) 0 clamp(34px, 4.4vw, 54px);
}
/* Not .display. The hero h1 clamps to 66px because it carries the whole page;
   a subpage title that size shouts, and the page below it is a list. */
.page-title {
  margin: 12px 0 20px;
  font-family: var(--font-display);
  font-size: clamp(31px, 4vw, 47px);
  line-height: 1.06;
  letter-spacing: -0.018em;
  font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
}

/* A table of contents, not a second nav. Seven pills in the header would be the
   mega-nav the competitor pass explicitly rejected. */
.svc-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: clamp(34px, 4.4vw, 54px);
  padding-bottom: clamp(26px, 3.4vw, 38px);
  border-bottom: 1px solid var(--stroke);
}
.svc-jump a {
  padding: 7px 13px;
  font-size: 13.5px;
  color: var(--ink-soft);
  text-decoration: none;
  border: 1px solid var(--stroke);
  border-radius: var(--r-structural);
}
.svc-jump a:hover { color: var(--accent); border-color: var(--accent-lift); }

.svc-detail { display: grid; gap: clamp(34px, 4.4vw, 56px); }
.svc-block {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  gap: clamp(20px, 3vw, 44px);
  padding-bottom: clamp(30px, 4vw, 46px);
  border-bottom: 1px solid var(--stroke-quiet);
}
.svc-block:last-child { border-bottom: 0; padding-bottom: 0; }
.svc-block h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(22px, 2.5vw, 30px);
  line-height: 1.12;
  font-weight: 600;
  color: var(--ink);
}
.svc-lead {
  grid-column: 1;
  margin: 12px 0 0;
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--ink-soft);
}
/* The facts sit in the second column, so the lead and the detail are two
   readable measures rather than one wide one. */
.svc-facts { grid-column: 2; grid-row: 1 / span 2; margin: 0; }
.svc-facts dt {
  margin-bottom: 4px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-mute);
}
.svc-facts dd {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.62;
  color: var(--ink-soft);
}
.svc-facts dd:last-child { margin-bottom: 0; }

@media (max-width: 900px) {
  .svc-block { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .svc-lead, .svc-facts { grid-column: 1; }
  .svc-facts { grid-row: auto; margin-top: 4px; }
}

/* The way out of an overview section into its full page. Right-aligned on wide
   screens so it reads as a continuation of the list it follows rather than a
   new item in it; left at the mobile breakpoint where nothing else is. */
.sec-more {
  margin: clamp(18px, 2.2vw, 26px) 0 0;
  font-size: 14.5px;
  text-align: right;
}
@media (max-width: 760px) {
  .sec-more { text-align: left; }
}

/* === XV-DEMO-RIBBON — added by scripts/import-site.py, not part of the site's source ===
   The ExVisio portfolio's DEMO ribbon, in this site's palette
   (scripts/portfolio-sites.json). Hidden only by recording-mode.mjs, for a take. */
.xv-demo-ribbon {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 9999;
  display: inline-flex; align-items: center;
  padding: .5em .85em;
  border: 1px solid var(--accent-lift); border-radius: var(--r-structural);
  background: var(--ground-lift);
  font-family: var(--font-sans); font-size: .72rem; font-weight: 600; letter-spacing: .04em;
  color: var(--ink-soft); text-decoration: none;
}
.xv-demo-ribbon:hover,
.xv-demo-ribbon:focus-visible { color: var(--accent); border-color: var(--accent); }
@media (max-width: 760px) { .xv-demo-ribbon { bottom: calc(76px + env(safe-area-inset-bottom)); } }
/* === end XV-DEMO-RIBBON === */
