/* ==========================================================================
   SALONI — Components
   Four primitives (DESIGN.md §4): the palm, the cone, the seed rule, the bloom.
   Everything here is built from those. Stroke over fill, always.
   ========================================================================== */

/* ---------------------------------------------------------------- icons */
.icon {
  inline-size: 1.5rem; block-size: 1.5rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.icon--lg { inline-size: 2.75rem; block-size: 2.75rem; stroke-width: 1.25; }
.icon--sm { inline-size: 1.125rem; block-size: 1.125rem; }

/* ---------------------------------------------------------------- buttons */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--fg);
  --btn-line: var(--line-strong);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-block-size: 3.25rem;
  padding-inline: var(--s-6);
  padding-block: var(--s-3);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--hair) solid var(--btn-line);
  border-radius: var(--r-sm);
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .01em;
  text-align: center;
  cursor: pointer;
  overflow: hidden;
  transition: background-color var(--t-micro) var(--e-out),
              color var(--t-micro) var(--e-out),
              border-color var(--t-micro) var(--e-out),
              transform var(--t-micro) var(--e-out);
}
html[lang="en"] .btn { text-transform: uppercase; letter-spacing: .09em; font-size: var(--fs-xs); }

.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* the cone — the henna applicator tip, used as the direction indicator.
   It always points along the reading direction and mirrors with dir.     */
.btn .cone {
  inline-size: .95rem; block-size: .95rem;
  flex: none;
  transition: transform 280ms var(--e-out);
}
.btn:hover .cone { transform: translateX(var(--cone-nudge, .28rem)); }

.btn--primary {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-on);
  --btn-line: var(--accent);
}
.btn--primary:hover { --btn-bg: var(--accent-soft); --btn-line: var(--accent-soft); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--fg); --btn-line: var(--line-2); }
.btn--ghost:hover { --btn-line: var(--accent); --btn-fg: var(--accent); }

.btn--onfield { --btn-bg: transparent; --btn-fg: var(--on-field); --btn-line: color-mix(in srgb, var(--on-field) 42%, transparent); }
.btn--onfield:hover { --btn-bg: var(--on-field); --btn-fg: var(--field); --btn-line: var(--on-field); }

.btn--solidfield { --btn-bg: #fff; --btn-fg: var(--mauve-5); --btn-line: #fff; }
.btn--solidfield:hover { --btn-bg: var(--peony); --btn-line: var(--peony); }

.btn--wa { --btn-bg: var(--leaf); --btn-fg: #fff; --btn-line: var(--leaf); }
[data-theme="dark"] .btn--wa { --btn-fg: var(--ink); }
.btn--wa:hover { --btn-bg: var(--leaf-soft); --btn-line: var(--leaf-soft); }

.btn--sm { min-block-size: 2.5rem; padding-inline: var(--s-4); font-size: var(--fs-xs); }
.btn--block { display: flex; inline-size: 100%; }

/* ---------------------------------------------------------------- panels */
/* "The palm" — a bordered field. Border is a stroke, never a shadow.      */
.panel {
  position: relative;
  background: var(--bg-2);
  border: var(--hair) solid var(--line);
  border-radius: var(--r-sm);
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  transition: border-color 260ms var(--e-out), background-color 260ms var(--e-out);
}
[data-theme="dark"] .panel { background: var(--bg-2); }

/* corner registration ticks — a drawn mark, not a shadow */
.panel::before,
.panel::after {
  content: "";
  position: absolute;
  inline-size: 11px; block-size: 11px;
  border: var(--hair) solid var(--accent);
  opacity: 0;
  transition: opacity 260ms var(--e-out);
  pointer-events: none;
}
.panel::before {
  inset-block-start: -1px; inset-inline-start: -1px;
  border-inline-end: 0; border-block-end: 0;
}
.panel::after {
  inset-block-end: -1px; inset-inline-end: -1px;
  border-inline-start: 0; border-block-start: 0;
}
.panel:hover::before, .panel:hover::after,
.panel:focus-within::before, .panel:focus-within::after { opacity: 1; }
.panel:hover { border-color: var(--line-2); }

.panel--field { background: var(--field-2); border-color: color-mix(in srgb, var(--on-field) 18%, transparent); color: var(--on-field); }
.panel--flat  { background: transparent; }

/* the arch — a shallow mihrab crown on the top edge. The radius is an
   ELLIPSE (wide × short), not a circle: a percentage on both axes builds a
   dome tall enough to cut through the panel's own content. */
.panel--arch {
  border-start-start-radius: 50% 3.25rem;
  border-start-end-radius: 50% 3.25rem;
  padding-block-start: clamp(2.75rem, 5vw, 4rem);
}
.panel--arch::before, .panel--arch::after { display: none; }

/* ---------------------------------------------------------------- blooms */
.bloom { color: var(--accent); }
.bloom svg { inline-size: 100%; block-size: 100%; fill: none; stroke: currentColor; stroke-width: 1.1; vector-effect: non-scaling-stroke; }

/* ---------------------------------------------------------------- badges */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: .4rem var(--s-3);
  border: var(--hair) solid currentColor;
  border-radius: 999px;
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--accent);
}
html[lang="ar"] .badge { text-transform: none; letter-spacing: 0; font-size: var(--fs-xs); }
.badge--sample {
  color: var(--fg-3);
  border-style: dashed;
  background: var(--bg-sunk);
}

/* ---------------------------------------------------------------- rating */
.rating { display: inline-flex; align-items: center; gap: var(--s-2); }
.rating__marks { display: inline-flex; gap: 3px; color: var(--accent); }
.rating__marks svg { inline-size: 1rem; block-size: 1rem; fill: currentColor; stroke: none; }
.rating__value { font-weight: 700; font-size: var(--fs-sm); }

/* ------------------------------------------------------------ medallions */
/* Monogram discs drawn in the world's grammar — never photographs of people */
.medallions { display: flex; align-items: center; }
.medallion {
  inline-size: 2.6rem; block-size: 2.6rem;
  margin-inline-end: -.65rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--field);
  color: var(--on-field-line);
  border: 1.5px solid var(--bg);
  font-family: var(--ff-display-ar);
  font-size: .95rem;
  font-weight: 600;
  position: relative;
}
.medallion:nth-child(2) { background: var(--peony); color: var(--mauve-5); }
.medallion:nth-child(3) { background: var(--leaf); color: #fff; }
.medallion:nth-child(4) { background: var(--mauve-2); color: #fff; }
.medallion:last-child { margin-inline-end: 0; }

/* --------------------------------------------------------------- header */
/* The bar is part of the field below it, not a strip laid on top of it: at
   the top of the page it is fully transparent so the hero's rose reads
   through as one uninterrupted surface, and once scrolled it fills with
   that same field so the merge survives the scroll instead of snapping
   back to the page ground.
   Its contents therefore take the on-field roles in BOTH themes — in light
   --accent IS --field, so the default nav colours would be the very colour
   they are printed on. --hd-* below resolve from the field, so one set of
   rules stays legible on rose (light) and on plum (dark).               */
.header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-nav);
  background: transparent;
  border-block-end: var(--hair) solid transparent;
  transition: border-color 300ms var(--e-out), background-color 300ms var(--e-out), transform 420ms var(--e-out);

  /* light: #fdf4f5 on #a24b57 = 5.4:1 · dark: #f4e9eb on #2a171d = 13.9:1 */
  --hd-fg:     var(--on-field);
  /* dimmed one step only — --on-field-dim is 3.7:1 on the light field     */
  --hd-fg-2:   color-mix(in srgb, var(--on-field) 90%, var(--field));
  --hd-line:   color-mix(in srgb, var(--on-field) 26%, transparent);
  --hd-line-2: color-mix(in srgb, var(--on-field) 50%, transparent);
  color: var(--hd-fg);
}
.header[data-scrolled="true"] {
  background: color-mix(in srgb, var(--field) 94%, transparent);
  border-block-end-color: color-mix(in srgb, var(--on-field) 16%, transparent);
  -webkit-backdrop-filter: saturate(1.15) blur(10px);
  backdrop-filter: saturate(1.15) blur(10px);
}
.header[data-hidden="true"] { transform: translateY(-102%); }

/* the ring is --accent, which is the field itself in light — lift it off */
.header :focus-visible { outline-color: var(--hd-fg); }

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-block-size: 4.5rem;
}

.brand { display: inline-flex; align-items: center; gap: var(--s-3); flex: none; }
.brand__mark { inline-size: 2.1rem; block-size: 2.1rem; color: var(--accent); }
.brand__name {
  font-family: var(--ff-display-en);
  font-size: 1.32rem;
  font-weight: 400;
  letter-spacing: .1em;
  color: var(--fg);
  line-height: 1;
}

/* the brand primitives are shared with the drawer, which sits on --bg —
   only the copies inside the header ride the field */
.header .brand__mark { color: var(--on-field-line); }
.header .brand__name { color: var(--hd-fg); }

.nav { display: flex; align-items: center; gap: var(--s-6); margin-inline: auto; }
.nav__link {
  position: relative;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--hd-fg-2);
  padding-block: var(--s-2);
  transition: color var(--t-micro) var(--e-out);
}
.nav__link::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 0;
  block-size: var(--hair);
  background: var(--on-field-line);
  transition: inline-size 260ms var(--e-out);
}
.nav__link:hover { color: var(--hd-fg); }
.nav__link:hover::after,
.nav__link[aria-current="true"]::after { inline-size: 100%; }
/* peony reads as text now the field is muted (5.4:1 light, 12:1 dark) —
   it was only 4:1 on the old saturated field */
.nav__link[aria-current="true"] { color: var(--on-field-line); }

.header__actions { display: flex; align-items: center; gap: var(--s-3); flex: none; }

/* -------------------------------------------------- segmented toggles */
.seg {
  display: inline-flex;
  border: var(--hair) solid var(--line);
  border-radius: 999px;
  padding: 2px;
  background: var(--bg-2);
}
.seg__btn {
  min-inline-size: 2.4rem;
  min-block-size: 2rem;
  padding-inline: var(--s-3);
  border-radius: 999px;
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--fg-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--t-micro) var(--e-out), color var(--t-micro) var(--e-out);
}
.seg__btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-on); }
.seg__btn:hover:not([aria-pressed="true"]) { color: var(--fg); }

/* on the field: the pressed pill inverts to on-field/field — --accent would
   be invisible in light, where it resolves to the field colour itself */
.header .seg {
  border-color: var(--hd-line);
  background: color-mix(in srgb, var(--on-field) 10%, transparent);
}
.header .seg__btn { color: var(--hd-fg-2); }
.header .seg__btn[aria-pressed="true"] { background: var(--hd-fg); color: var(--field); }
.header .seg__btn:hover:not([aria-pressed="true"]) { color: var(--hd-fg); }

.icon-btn {
  inline-size: 2.75rem; block-size: 2.75rem;
  display: grid; place-items: center;
  border: var(--hair) solid var(--line);
  border-radius: 999px;
  color: var(--fg-2);
  transition: color var(--t-micro) var(--e-out), border-color var(--t-micro) var(--e-out);
}
.icon-btn:hover { color: var(--accent); border-color: var(--accent); }

.header .icon-btn { color: var(--hd-fg-2); border-color: var(--hd-line); }
.header .icon-btn:hover { color: var(--hd-fg); border-color: var(--hd-line-2); }

.theme-toggle .icon { transition: transform 480ms var(--e-out), opacity 240ms var(--e-out); }
.theme-toggle .icon--moon { display: none; }
[data-theme="dark"] .theme-toggle .icon--sun { display: none; }
[data-theme="dark"] .theme-toggle .icon--moon { display: block; }

/* ------------------------------------------------------- mobile drawer */
.burger { display: none; }

.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  background: var(--bg);
  padding: var(--s-6) var(--gutter) var(--s-8);
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform 480ms var(--e-out), visibility 480ms;
  overflow-y: auto;
}
.drawer[data-open="true"] { transform: translateY(0); visibility: visible; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; }
.drawer__nav { display: flex; flex-direction: column; gap: var(--s-2); }
.drawer__link {
  font-family: var(--ff-display);
  font-size: clamp(1.9rem, 8vw, 2.6rem);
  font-weight: 600;
  padding-block: var(--s-3);
  border-block-end: var(--hair) solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.drawer__link .cone { inline-size: 1.1rem; block-size: 1.1rem; color: var(--accent); }
.drawer__foot { margin-block-start: auto; display: grid; gap: var(--s-4); }
.drawer__row { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }

/* ------------------------------------------------------------- fields */
.field { display: grid; gap: var(--s-2); }
.field__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--fg-2);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.field__req { color: var(--accent); }

.input, .select {
  inline-size: 100%;
  min-block-size: 3.25rem;
  padding: var(--s-3) var(--s-4);
  background: var(--bg);
  color: var(--fg);
  border: var(--hair) solid var(--line-2);
  border-radius: var(--r-sm);
  font-size: var(--fs-body);
  transition: border-color var(--t-micro) var(--e-out), background-color var(--t-micro) var(--e-out);
}
.input::placeholder { color: var(--fg-3); opacity: 1; }
.input:hover, .select:hover { border-color: var(--fg-3); }
.input:focus-visible, .select:focus-visible { border-color: var(--accent); outline-offset: 1px; }

.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-inline-end: var(--s-9);
}
[dir="rtl"] .select {
  background-position: 20px calc(50% + 2px), 14px calc(50% + 2px);
  background-image: linear-gradient(135deg, currentColor 50%, transparent 50%),
                    linear-gradient(45deg, transparent 50%, currentColor 50%);
}

.field[data-invalid="true"] .input,
.field[data-invalid="true"] .select { border-color: var(--err); }

.field__error {
  font-size: var(--fs-xs);
  color: var(--err);
  display: none;
  align-items: center;
  gap: var(--s-2);
}
.field[data-invalid="true"] .field__error { display: flex; }

.phone-row { display: grid; grid-template-columns: 8.5rem 1fr; gap: var(--s-3); }

/* ------------------------------------------------ searchable combobox */
/* Progressive: the native <select> is what ships in the markup and what
   still works with JS off. app.js marks the field ready, which reveals the
   combobox and takes the select out of the visual and tab order — it stays
   in the DOM as the value that is read and validated. */
.field--country .combo { display: none; }
.field--country[data-combo="ready"] .combo { display: block; position: relative; }
.field--country[data-combo="ready"] > .select {
  position: absolute;
  inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.combo__input { padding-inline: 2.9rem; }
.combo__glass {
  position: absolute;
  inset-inline-start: var(--s-4);
  inset-block-start: 50%;
  transform: translateY(-50%);
  color: var(--fg-3);
  pointer-events: none;
}
/* the caret is two strokes turned, like the FAQ sign — never a glyph */
.combo__caret {
  position: absolute;
  inset-inline-end: 1.2rem;
  inset-block-start: 50%;
  inline-size: 6px; block-size: 6px;
  border-inline-end: 1.5px solid currentColor;
  border-block-end: 1.5px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  color: var(--fg-3);
  transition: transform var(--t-micro) var(--e-out);
  pointer-events: none;
}
.combo[data-open="true"] .combo__caret { transform: translateY(-30%) rotate(225deg); }

.combo__list, .combo__none {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% + 6px);
  z-index: 20;
  background: var(--bg-2);
  border: var(--hair) solid var(--line-2);
  border-radius: var(--r-sm);
}
.combo__list {
  max-block-size: 16rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-2);
  display: grid;
  gap: 2px;
}
.combo__list[hidden], .combo__none[hidden] { display: none; }
.combo__opt {
  display: flex;
  align-items: center;
  min-block-size: 2.75rem;
  padding: .5rem var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  color: var(--fg-2);
  cursor: pointer;
}
.combo__opt[data-active="true"] { background: var(--accent-wash); color: var(--accent); }
.combo__opt[aria-selected="true"] { color: var(--fg); font-weight: 700; }
.combo__none {
  padding: var(--s-4);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--fg-3);
}

/* choice pills (female-consultant preference) */
.choices { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.choice { position: relative; }
.choice input {
  position: absolute; opacity: 0;
  inline-size: 100%; block-size: 100%;
  margin: 0; cursor: pointer;
}
.choice__face {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: 3rem;
  padding-inline: var(--s-5);
  border: var(--hair) solid var(--line-2);
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--fg-2);
  transition: all var(--t-micro) var(--e-out);
}
.choice input:hover + .choice__face { border-color: var(--fg-3); }
.choice input:focus-visible + .choice__face { outline: var(--focus-w) solid var(--accent); outline-offset: var(--focus-off); }
.choice input:checked + .choice__face {
  border-color: var(--accent);
  background: var(--accent-wash);
  color: var(--accent);
}
.choice__face .icon { inline-size: 1.1rem; block-size: 1.1rem; }

/* ------------------------------------------------------------- notice */
.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4);
  border: var(--hair) dashed var(--line-2);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  color: var(--fg-3);
  line-height: 1.6;
}
.notice .icon { color: var(--leaf); margin-block-start: .1rem; }

/* -------------------------------------------------------- stat panels */
.stat { display: grid; gap: var(--s-2); }
.stat__value {
  font-family: var(--ff-display);
  font-size: clamp(2rem, 3.4vw, 3rem);
  font-weight: 600;
  line-height: 1;
  color: var(--accent);
}
.stat__label { font-size: var(--fs-xs); color: var(--fg-3); line-height: 1.5; }
.section--field .stat__value { color: var(--on-field-line); }
.section--field .stat__label { color: var(--on-field-dim); }

/* ------------------------------------------------------- the connector */
/* Section-to-section graphics. One vine, drawn on scroll, blooming where
   it arrives. Entry x of each connector matches the previous exit x so the
   whole page reads as a single continuous line. (DESIGN.md §1)

   ASPECT: this block previously set a fixed height and let the SVG stretch
   with preserveAspectRatio="none". At 1900x160 against a 1440x190 viewBox
   that is a 2.2:1 non-uniform scale — every rosette flattened into a smear
   and every leaf into a sliver, which is what made the ornament read as
   crude. The band now carries the artwork's own aspect ratio and the SVG
   scales uniformly, so a circle stays a circle at every width.          */
.connector {
  position: relative;
  /* inline-size must be DEFINITE. aspect-ratio is bidirectional: once a
     min-block-size wins over the height the ratio would derive from the
     width, the ratio runs backwards and derives the WIDTH from that height
     instead — 5.5rem x 1440/190 = 667px, which dragged the whole document
     to 667px wide inside a 390px viewport. Pinning the inline size leaves
     the ratio only one direction to work in. */
  inline-size: 100%;
  aspect-ratio: 1440 / 190;

  /* The band must never be TALLER than the artwork's own ratio. "slice"
     scales by whichever axis needs the most to cover the box, so the moment
     a min-block-size made the band taller than 1440:190 it began scaling by
     HEIGHT and cropping the WIDTH — and the vine is a drawing whose whole
     subject is its width. Measured at 360px, the old 5.5rem floor left only
     x 331..1109 of 1440 visible: 46% of every vine thrown away, including
     the edge the line enters from and the rosette at the far end. Height is
     therefore clamped in one direction only, downward, which keeps the scale
     at bandWidth/1440 at every size and the drawing whole across the screen.

     Clamping downward crops top and bottom instead, which is harmless — the
     spines are deliberately drawn past both edges (the M… -50 / L… 240
     segments) so the line runs off the band rather than stopping in it. The
     floor of the cap protects the ornaments: their envelope reaches 80 units
     either side of the vine's centre line, so the visible window must stay
     at least 160 units tall, and 11.5vw holds it at ~166 however wide the
     screen gets. Below ~2780px the 20rem term governs and nothing is cropped
     at all. */
  max-block-size: max(20rem, 11.5vw);
  overflow: hidden;
  pointer-events: none;
}
.connector svg { inline-size: 100%; block-size: 100%; display: block; }

/* The band is 1440:190, and the vine only occupies its upper two thirds —
   the rest is the run-out the spine needs to leave the frame cleanly. A full
   --section-pad on top of that run-out put roughly 160px of nothing between
   the drawing and the heading it is supposed to be handing off to, which is
   what made the graphic read as stranded. The section that RECEIVES the line
   takes a reduced pad; every other section keeps the page's rhythm. */
.connector + .section { padding-block-start: calc(var(--section-pad) * .34); }
/* two bands in a row are one longer gesture, not two graphics with a gap */
.connector + .connector { margin-block-start: calc(var(--section-pad) * -.08); }

/* the vine's parts, by role. Stroke over fill, always (DESIGN.md §1). */
.connector .vine-spine,
.connector .vine-branch {
  fill: none;
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.connector .vine-spine  { stroke-width: 1.5; }
.connector .vine-branch { stroke-width: 1; opacity: .72; }

/* vector-effect does not inherit, so naming it on the group set it on
   nothing that draws: every ornament stroke was scaling with the band —
   1.5px at 1900px, and 0.29px at 360px, which is why the ornaments washed
   out to almost nothing on a phone while the spine beside them stayed
   crisp. Naming the shapes themselves holds every mark at its authored
   hairline at any size, which is the point of drawing in stroke.

   These two are deliberately NOT scoped under .connector. A <use> renders
   into a shadow tree that no descendant selector can reach, so if the
   ornaments are ever left un-inlined the scoped rules all miss and the
   clone falls back to the initial fill — a solid black disc where a
   hairline rosette should be. Scoping to the library instead means the
   fill is answered for on the original, and inherits into the clone. */
.orn { fill: none; }
.orn path,
.orn circle { vector-effect: non-scaling-stroke; }
.connector .orn-petal  { stroke: var(--accent);    stroke-width: 1.15; }
.connector .orn-core   { stroke: var(--accent);    stroke-width: 1.15; }
.connector .orn-leaf   { stroke: var(--leaf);      stroke-width: 1.1; }
.connector .orn-hatch  { stroke: var(--leaf-soft); stroke-width: .8; opacity: .8; }
.connector .orn-seed   { fill: var(--accent); stroke: none; }
.connector .orn-seed--leaf { fill: var(--leaf); }

/* on the committed field the same vine switches to its on-field roles */
.connector--onfield .vine-spine,
.connector--onfield .vine-branch,
.connector--onfield .orn-petal,
.connector--onfield .orn-core  { stroke: var(--on-field-line); }
.connector--onfield .orn-leaf  { stroke: var(--sage-2); }
.connector--onfield .orn-hatch { stroke: var(--sage-2); opacity: .6; }
.connector--onfield .orn-seed  { fill: var(--on-field-line); }
.connector--onfield .orn-seed--leaf { fill: var(--sage-2); }
.connector--onfield .vine-spine { stroke-width: 1.7; }

/* Each ornament is hidden until the drawn line actually reaches it, so the
   page reads as one gesture arriving rather than as decoration fading in.
   motion.js keys this to the spine's own draw progress. Without JS (or with
   reduced motion) they are simply present — see the .is-anim guard.     */
.is-anim .connector [data-orn] { opacity: 0; }

/* --------------------------------------------------------- petal field */
.petals {
  position: absolute;
  inset: 0;
  inline-size: 100%; block-size: 100%;
  pointer-events: none;
  opacity: .5;
}
