/* Canitdo — opening page (pin-line concept).
   Sibling to styles.css; scoped under .op-* so it never touches index.html.
   Palette continuous with styles.css: warm-white ground, brand green kept
   ONLY as the wordmark's own drop-shadow. Hairlines are charcoal on white. */

/* Self-hosted UI fonts (OFL, embed + deploy freely). Both wired; switch the
   active one on --op-font below. */
@font-face {
  font-family: "Original Surfer";
  src: url("assets/fonts/OriginalSurfer-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Ruda";
  src: url("assets/fonts/Ruda-VariableFont_wght.ttf") format("truetype");
  font-weight: 400 900;              /* variable weight axis */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("assets/fonts/Poppins-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("assets/fonts/Poppins-Medium.ttf") format("truetype");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("assets/fonts/Poppins-SemiBold.ttf") format("truetype");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("assets/fonts/Poppins-Bold.ttf") format("truetype");
  font-weight: 700; font-style: normal; font-display: swap;
}
/* Stardos Stencil — used ONLY for the "Specialist" lockup word. */
@font-face {
  font-family: "Stardos Stencil";
  src: url("assets/fonts/StardosStencil-Regular.ttf") format("truetype");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Stardos Stencil";
  src: url("assets/fonts/StardosStencil-Bold.ttf") format("truetype");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* --- inherited feel from styles.css --- */
  --op-ground:   #ffffff;
  --op-warm:     #fbfbf9;      /* faint warm-white wash */
  --op-ink:      #123528;      /* brand darkest green (labels darken toward this) */
  --op-mark-green: #2f4139;    /* sampled from the logo letters (a, i) */
  --op-charcoal: #1c1c1a;      /* near-black hairline */
  --op-muted:    #8a938c;      /* resting label colour — quiet */
  --op-font: "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* ============================================================
     TUNABLE PIN-LINE GEOMETRY
     ------------------------------------------------------------
     SOURCE OF TRUTH for the LINE SHAPE is the inline SVG <path>s in
     opening.html — they're drawn in the wordmark's own coordinate
     space (viewBox 0 0 2000 900, matching the 2000x516 source PNG +
     384u headroom). That's why the origin lands on the letter with no
     guesswork and holds at every screen size.

     Measured from the PNG: the mark is lowercase-dotted — it reads
     CAN-i-TDO with a real dotted "i". The pins EXIT THE BOTTOM of the
     "i" stem at the baseline (not the top / dot), then drop and turn.
     The stem centre sits at x=1046 (stem spans x995-1098) => 52.3%.

     TO NUDGE (edit the two <path> d="" values in opening.html):
       origin left/right -> change the two X values (now 1043 & 1049;
                            keep them straddling 1046 for a centred gap)
       gap between lines -> widen/narrow the 1043<->1049 spread (6u ~= 3px)
       vertical drop     -> lines start at the "i" baseline (~490) and turn
                            at y640; change the middle Y to lengthen the drop
       arm length        -> change the final X on each path
                            (left end 780, right end 1299)

     The custom-properties below are the CSS-side mirror. They govern the
     hairline weight/colour and the DOM label + input anchoring, and are
     kept in the SAME 2000u space via calc(<u> / 2000 * --op-w). The
     annotated *px equivalents* are what they read as at the 560px default.
     If you re-tune the SVG, update the matching numbers in
     .op-label--left / --right and .op-inputwrap to keep labels on the arms.
     ============================================================ */

  --pin-origin-x: 52.3%;         /* centre of the "I" stem (=1046/2000) */
  --pin-gap: 3px;                /* space between the two parallel lines (2-4px) => 6u */
  --pin-drop: 74px;             /* short vertical run below the baseline before turns => ~55u visible */
  --pin-arm: 132px;             /* horizontal length of each arm (L & R) => ~264u */
  --pin-weight: 1px;            /* hairline thickness */
  --pin-color: var(--op-charcoal);

  --pin-label-gap: 14px;        /* space between an arm's end and its label */
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }

body.op-body {
  font-family: var(--op-font);
  color: var(--op-ink);
  background:
    radial-gradient(120% 80% at 50% 38%, var(--op-ground) 0%, var(--op-warm) 100%);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  height: 100vh;
  overflow: hidden;               /* no-scroll opening */
}

.op-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---- client sign-in (quiet corner link) --------------------------- */
/* Out of the composition, top-right. Muted at rest, resolves toward ink on
   hover — same language as the path labels. Kept small but above the 13px
   label floor. */
.op-signin {
  position: fixed;
  top: clamp(1rem, 3vh, 1.75rem);
  right: clamp(1rem, 4vw, 2.25rem);
  z-index: 5;
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--op-muted);
  text-decoration: none;
  padding: 0.35em 0.1em;
  transition: color 160ms ease;
}
.op-signin:hover,
.op-signin:focus-visible {
  color: var(--op-ink);
}

/* ---- Subscription Hunter (the mission — mix of both worlds, centred) --- */
.op-sub-wrap {
  position: fixed;
  left: 50%;
  bottom: clamp(1rem, 4vh, 2.5rem);
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: min(92vw, 32rem);
}
/* The mission statement, hidden until you reach for Subscription Hunter. */
.op-sub-mission {
  margin: 0 0 0.7em;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--op-muted);
  opacity: 0;
  filter: blur(6px);
  transform: translateY(6px);
  pointer-events: none;
  transition: opacity 380ms ease, filter 380ms ease, transform 380ms ease;
}
/* Trigger ONLY when the pointer/focus is on the Subscription Hunter link
   itself — NOT anywhere in .op-sub-wrap. The wrap is a tall column whose
   invisible mission region reaches up the page centre and overlaps the comms
   dropdown; a wrap-level :hover let the comms menu trip the mission. :has scopes
   the trigger to the link so the two never interfere. (You have to be right on
   Subscription Hunter to get the message.) */
.op-sub-wrap:has(.op-sub:hover) .op-sub-mission,
.op-sub-wrap:has(.op-sub:focus-visible) .op-sub-mission {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
/* The two paths inside the mission, each tinted + arrowed toward its own door:
   build -> right (blue), empower <- left (seafoam). Readable dark tints on white. */
.op-sub-path { font-weight: 500; }
.op-sub-path--build   { color: #2b8aa6; }   /* build blue — points to the right door  */
.op-sub-path--empower { color: #2f9e86; }   /* empower seafoam — points to the left door */
.op-sub-arrow { font-weight: 700; }
.op-sub {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--op-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 200ms ease, text-shadow 200ms ease;
}
.op-sub:hover,
.op-sub:focus-visible {
  color: var(--op-ink);          /* the mix: both sides' glow, seafoam + blue */
  text-shadow: 0 0 5px var(--glow-green), 0 0 12px var(--glow-blue);
}

/* ---- per-side reveal panels (click a door to open) ----------------- */
/* Anchored inside .op-composition so they track the door labels' coordinate
   space: the panel top begins ~20px ABOVE the label and the list builds
   DOWNWARD. On open the item names sweep in (soft mask); hovering an item
   sweeps in its description beside it (right of the name on Empower, left on
   Build). Names link to their dedicated tab later. */
.op-reveal {
  position: absolute;
  z-index: 4;
  top: calc(990 / 2000 * var(--op-w) - 40px);   /* 40px above the label; builds down (raised 20px) */
  max-width: min(46vw, 34rem);
  pointer-events: none;                          /* items opt back in */
}
.op-reveal[hidden] { display: none; }
/* The composition is centred + narrow, so anchoring the panels to ITS edges
   pulled them toward the middle. Reach back out to ~2rem from the screen edges
   (the vertical stays anchored 20px above the label). */
.op-reveal--empower { left:  calc(2rem + 50px - (100vw - var(--op-w)) / 2); text-align: left;  }
.op-reveal--build   { right: calc(2rem + 50px - (100vw - var(--op-w)) / 2); text-align: right; }

.op-menu { list-style: none; margin: 0; padding: 0; }

/* Interactive bits opt back into pointer events (the panel itself is none). */
.op-item-name, .op-back, .op-book { pointer-events: auto; }

/* ---- LEVEL 1: the four sessions (name over a short hook) ------------- */
.op-item2 { margin: 0.7em 0; }
.op-item-name {
  display: inline-block;
  font-weight: 600;
  font-size: clamp(15px, 1.6vw, 18px);
  color: var(--op-ink);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: text-shadow 180ms ease;
}
.op-item-hook {
  display: block;
  margin-top: 2px;
  font-size: clamp(12px, 1.2vw, 13.5px);
  line-height: 1.4;
  color: var(--op-muted);
}
.op-reveal--empower .op-item-name:hover { text-shadow: 0 0 5px var(--glow-green), 0 0 12px var(--glow-green); }
.op-reveal--build   .op-item-name:hover { text-shadow: 0 0 5px var(--build-hi),  0 0 12px var(--build-hi); }

/* ---- LEVEL 2: a session's own screen (back + title + sub-items) ------ */
.op-back {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 0.05em; margin: 0 0 0.9em;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit;
  color: var(--op-muted); transition: color 180ms ease;
}
/* The arrow rides LARGE above the door label so the way back is unmissable
   from inside a session (Josh, S9). Label stays quiet beneath it. */
.op-back-arrow { font-size: clamp(22px, 2.4vw, 28px); line-height: 1; }
.op-back-label { font-size: clamp(13px, 1.2vw, 14px); }
.op-back:hover { color: var(--op-ink); }
/* Build side: the column is right-aligned — the back block hugs that edge. */
.op-reveal--build .op-back { align-items: flex-end; }
.op-sub-title {
  font-weight: 600;
  font-size: clamp(17px, 1.9vw, 21px);
  color: var(--op-ink);
  margin: 0 0 0.8em;
}
/* Sub-items: three quiet text rows in the page's own type language. */
.op-subitems { display: flex; flex-direction: column; gap: 0.5em; margin: 0 0 0.9em; max-width: 20em; }

/* Level 2 lays the sub-items BESIDE the title (not stacked under it) and lifts
   the whole block up toward the wordmark. Two knobs to tune live:
     --l2-lift  = how far UP (more negative = higher, closer under the mark)
     --l2-gap   = space between the title and the sub-items column */
.op-l2row { display: flex; gap: var(--l2-gap, 1.6em); align-items: flex-start; }
.op-reveal--build .op-l2row { flex-direction: row-reverse; }
.op-sub-title { flex: none; margin: 0; }
.op-l2body { min-width: 0; }
.op-level.is-l2 { transform: translateY(var(--l2-lift, -3rem)); }
/* One sub-item line. Readable but calmer than the title (weight 400, smaller).
   --l2-sub-color is a knob: a softened dark green-grey, nudge by eye. */
.op-subitem {
  font-size: clamp(13.5px, 1.4vw, 15px);
  line-height: 1.45;
  font-weight: 400;
  color: var(--l2-sub-color, #34473e);
}
.op-reveal--build .op-subitems { margin-left: auto; }   /* anchor the column to the right on Build */
/* The shared consult line, quiet, sitting right above the book CTA. */
.op-consult {
  max-width: 24em;
  font-size: clamp(13px, 1.25vw, 14px);
  line-height: 1.5;
  color: var(--op-muted);
  margin: 0 0 1em;
}
.op-reveal--build .op-consult { margin-left: auto; }
.op-book {
  display: inline-block; text-decoration: none;
  font-weight: 600; font-size: clamp(13px, 1.3vw, 14px);
  cursor: pointer; transition: text-shadow 180ms ease;
}
.op-reveal--empower .op-book { color: #2f9e86; }
.op-reveal--build   .op-book { color: #2b8aa6; }

/* ---- door strip: one quiet line under the four sessions (level 1 only) ----
   Tinted with the door's identity but smaller + lighter than the menu names,
   so it stays under them in weight. Colour knobs (readable members of the
   door families): Empower = seafoam green, Build = warm gold (--build-hi hue).
   Strip text floor is 14px. */
:root {
  --strip-empower: #2f9e86;   /* Empower door green — matches the book/mission seafoam */
  --strip-build:   #b5872b;   /* Build door gold — the readable-on-white member of the --build-hi family */
}
.op-strip {
  margin: 1.5em 0 0;          /* clear separation from the sessions above */
  max-width: 22em;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0.005em;
}
.op-reveal--empower .op-strip { color: var(--strip-empower); }
.op-reveal--build   .op-strip { color: var(--strip-build); margin-left: auto; }  /* anchor right on Build */

/* Build side mirrors right. */
.op-reveal--build .op-level { text-align: right; }

/* ---- level swap: children ease up out of a soft blur (Josh's reveal) - */
.op-item2, .op-back, .op-sub-title, .op-subitems, .op-consult, .op-book, .op-strip {
  opacity: 0;
  filter: blur(4px);
  transition: opacity 500ms ease, filter 500ms ease, text-shadow 180ms ease;
}
.op-level.is-in .op-item2,
.op-level.is-in .op-back,
.op-level.is-in .op-sub-title,
.op-level.is-in .op-subitems,
.op-level.is-in .op-consult,
.op-level.is-in .op-book,
.op-level.is-in .op-strip { opacity: 1; filter: blur(0); }
.op-level.is-in .op-item2:nth-child(2) { transition-delay: 90ms; }
.op-level.is-in .op-item2:nth-child(3) { transition-delay: 180ms; }
.op-level.is-in .op-item2:nth-child(4) { transition-delay: 270ms; }
.op-level.is-in .op-strip { transition-delay: 360ms; }   /* lands after the four sessions */

/* ---- shimmer: ONLY "Expanded techniques", ONLY on click (locked spec)
   Rests normal; on click a purple wave sweeps across (starts on the first
   letter, 5.2s linear) then hands off into the session screen. ---------- */
.op-shim.run {
  color: transparent; -webkit-text-fill-color: transparent;
  background-image: linear-gradient(100deg, var(--op-ink) 0%, var(--op-ink) 40%, #8b5cf6 50%, var(--op-ink) 60%, var(--op-ink) 100%);
  background-size: 260% 100%; background-position: 92% 0;
  -webkit-background-clip: text; background-clip: text;
  animation: ct-sweep 1.3s linear forwards;
}
@keyframes ct-sweep { from { background-position: 92% 0; } to { background-position: 8% 0; } }

@media (prefers-reduced-motion: reduce) {
  .op-item2, .op-back, .op-sub-title, .op-subitems, .op-consult, .op-book, .op-strip {
    transition: text-shadow 180ms ease; filter: none;
  }
}

/* When a side is opened (clicked), its door label + pin line step aside so the
   typed panel takes over. Independent per side. */
.op-composition.is-open-empower .op-label--left,
.op-composition.is-open-build   .op-label--right {
  animation: none;                /* release the intro op-rise forwards-fill, which
                                     otherwise pins opacity at 1 and blocks the hide */
  opacity: 0;
  pointer-events: none;
}
.op-composition.is-open-empower .op-pin--left,
.op-composition.is-open-build   .op-pin--right { opacity: 0; pointer-events: none; }
.op-composition.is-open-empower .op-pin-hit[data-side="empower"],
.op-composition.is-open-build   .op-pin-hit[data-side="build"] { pointer-events: none; }

/* Full-viewport stage; wordmark sits near the TOP with breathing room. */
.op-stage {
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 6vh clamp(1rem, 4vw, 3rem) clamp(1.25rem, 4vh, 3rem);
}

/* Top-aligned composition; the diagram + input breathe below the wordmark.
   --op-w is the rendered wordmark width; every SVG-anchored offset below is
   expressed as (svg_units / 2000) * --op-w so DOM elements land on the exact
   SVG endpoints regardless of screen size. */
.op-composition {
  --op-w: min(88vw, 560px);
  position: relative;
  isolation: isolate;            /* own stacking context: layer glow BEHIND the mark */
  width: var(--op-w);            /* controls rendered wordmark width */
  transform: translateY(15vh);   /* Josh: whole composition shifted DOWN 15% */
  /* The mark + SVG pins are graphics — clicking a pin line was selecting the SVG
     and drawing a persistent selection box. Kill selection here; re-enable on the
     text input below so it stays usable. */
  -webkit-user-select: none;
  user-select: none;
}
.op-input { -webkit-user-select: text; user-select: text; }

/* ---- the wordmark ------------------------------------------------- */
.op-mark {
  display: block;
  z-index: 2;                    /* mark sits ABOVE the glow, so the black letters
                                    occlude it — the glow is a halo, never on-face */
  width: 100%;
  height: auto;
  /* v2 logo (CIDv2) is a full 3D render with its OWN baked-in shadow/depth —
     do NOT add a CSS drop-shadow on top. Stacking a second shadow was
     darkening and muddying Josh's clean mark ("shadow on the shadow"). */
}
/* The 3D mark is in flow and owns the composition's height. After the intro it
   fades to opacity 0 and stays there — the per-side glow halves do the hover 3D. */
.op-mark--3d   { position: relative; opacity: 0; }
/* The flat mark is a GROUP overlaying the 3D pixel-for-pixel (same 2000x519). It
   crossfades in on load; its three pieces then fade independently on hover. */
.op-mark--flat { position: absolute; top: 0; left: 0; width: 100%; opacity: 1; }
.op-flat-piece {
  position: absolute; top: 0; left: 0;
  display: block; width: 100%; height: auto;
  opacity: 1;
  transition: opacity 0.32s ease;
}
/* Hover a side -> fade that half of the flat (incl. the shared i), revealing the
   glowing 3D beneath; the other half stays flat. The is-open-<side> variants keep
   that side's 3D held while its menu is open, until the wordmark is clicked. */
.op-composition[data-hover="empower"] .op-flat--can,
.op-composition[data-hover="empower"] .op-flat--i,
.op-composition.is-open-empower       .op-flat--can,
.op-composition.is-open-empower       .op-flat--i,
.op-composition[data-hover="build"]   .op-flat--tdo,
.op-composition[data-hover="build"]   .op-flat--i,
.op-composition.is-open-build         .op-flat--tdo,
.op-composition.is-open-build         .op-flat--i { opacity: 0; }

/* ---- per-side glow overlays -------------------------------------- */
/* Two extra copies of the mark, stacked pixel-perfect over .op-mark.
   Each is tinted by a coloured drop-shadow() (which follows the PNG's
   alpha, so the glow traces the LETTERS, never a rectangle) and clipped
   to one half of the wordmark. Both rest invisible; the composition's
   data-side (select) / data-hover (hover) attributes fade one in.

   Colour tokens — light, neon "hologram" glow (Josh 2026-07-05). Bright and
   luminous so the bloom reads as a halo on the BLACK items against white:
     green: light neon mint-green
     blue:  light neon cyan-blue   */
:root {
  --glow-green: rgba(116, 226, 210, 0.9);   /* Empower primary glow (reads as the darker green) */
  --glow-blue:  rgba(102, 232, 255, 0.9);   /* Build primary — light neon cyan-blue */
  /* Second glow layer (Josh's technique, 07-06): a duplicate of each primary in a
     different colour, offset down-right and sitting UNDERNEATH so a thin line just
     peeks out. Not blended — two distinct layers. */
  --glow-seafoam: rgba(150, 255, 240, 0.95);/* light seafoam turquoise — peeks under Empower's green */
  --glow-yellow:  rgba(245, 196, 98, 0.45); /* light warm gold — peeks under Build's blue (dialled down so the covered part barely tints) */
  --peek-x: 3px;                            /* how far RIGHT the peek sits (tunable) */
  --peek-y: 4px;                            /* how far DOWN the peek sits (tunable) */
  /* Per-side identity now lives in the PIN LINE + WORD HIGHLIGHTS, not the mark
     (Josh 07-06). The wordmark shading is uniform on both halves; the side you're
     on is told by these colours: Build = yellow, Empower = green (--glow-green). */
  --build-hi: rgba(245, 196, 98, 0.95);     /* Build's pin + word-highlight — light warm gold (a real glow, not the faint peek) */
}

.op-glow {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;                    /* BEHIND the mark — halo bleeds out, occluded on-letter */
  width: 100%;
  height: auto;
  display: block;
  opacity: 0;                    /* neutral/clean by default */
  transition: opacity 0.3s ease;
  pointer-events: none;          /* never intercepts; labels/lines do */
  /* NO will-change here: permanent promotion kept the whole composition
     composited and dragged all panel text into grayscale rendering (S9).
     The opacity transition promotes on demand — smoothness unchanged. */
}

/* GREEN = left half (C A N i). A soft MASK fades it out through the i (no
   hard clip edge). Two stacked drop-shadows: a tight core + a softer bloom
   = a glow that hugs each letterform, following the PNG alpha. */
.op-glow--green {
  /* LEFT half of the mark — C-A-N-i only. The stray T-tip baked into this half in
     error is ERASED from the PNG at the clean gap past the i (x1059). (The ghost
     "line" beside the dot was a flat-i edge sliver stuck in the TDO piece — fixed by
     the piece split, not here — so the glow stays the original tight neon.) */
  /* Unified shading (Josh 07-06): the left half now uses the SAME blue + yellow
     peek as the it-do side, so the wordmark carries no per-side colour. */
  filter:
    drop-shadow(0 0 2px var(--glow-blue))
    drop-shadow(0 0 3px var(--glow-blue))
    drop-shadow(var(--peek-x) var(--peek-y) 0.5px var(--glow-yellow));
}

/* BLUE = right half (i T D O). A soft MASK fades it IN through the i,
   mirroring the green fade so the two cross-fade at the i with no clip box. */
.op-glow--blue {
  /* RIGHT half of the mark (canitdo-mark-right.png) — only i-T-D-O pixels.
     Mirror of green: a gradient mask fades the glow out in the empty N–i gap so
     the blue bloom can't reach the N on Build hover. Fade is in empty space => no box. */
  filter:
    drop-shadow(0 0 2px var(--glow-blue))
    drop-shadow(0 0 3px var(--glow-blue))     /* primary Build blue */
    drop-shadow(var(--peek-x) var(--peek-y) 0.5px var(--glow-yellow));  /* yellow peek — hairline (0.5px) so overlap with the blue is minimal */
  -webkit-mask-image: linear-gradient(to right, transparent 45.5%, #000 47.5%);
          mask-image: linear-gradient(to right, transparent 45.5%, #000 47.5%);
}

/* --- reveal logic: HOVER ONLY --------------------------------------- */
/* Glow shows only while a side is hovered. No persistent select — the glow
   must never stick after the pointer leaves (Josh 2026-07-05). */
.op-composition[data-hover="empower"] .op-glow--green,
.op-composition.is-open-empower       .op-glow--green { opacity: 1; }
.op-composition[data-hover="build"]   .op-glow--blue,
.op-composition.is-open-build         .op-glow--blue  { opacity: 1; }

/* ---- confetti horn (celebration on opening "Empower me") ------------- */
/* A tiny party-popper anchored to the C of the wordmark. JS (fireConfetti)
   pops the horn + spawns seafoam-green particles on each Empower open, then
   clears them. The host is a zero-size point; horn + particles centre on it.
   EVERYTHING here is pointer-events:none, so the celebration never blocks a
   click. Anchor knobs are % of the mark's box (composition height == mark
   height) — measured to the C; nudge --confetti-x / --confetti-y by eye. */
:root {
  --confetti-x: 3.2%;    /* horizontal: the C's upper-LEFT shoulder (~x64 / 2000, PIL-measured; Josh, S9) */
  --confetti-y: 7.5%;    /* vertical: just above the shoulder's top edge (~row 39 / 519) */
  --horn-size:  30px;    /* the party-popper graphic size */
  --horn-rot:   -60deg;  /* mouth direction: -60deg = ten o'clock (Josh, S9) */
}
.op-confetti {
  position: absolute;
  left: var(--confetti-x, 18%);
  top:  var(--confetti-y, 9%);
  width: 0; height: 0;
  z-index: 6;            /* rides above the mark/menus; pointer-events:none => blocks nothing */
  pointer-events: none;
}
.op-confetti * { pointer-events: none; }

/* The horn graphic: invisible at rest, pops on .is-blasting (full) or .is-pop
   (the gentle reduced-motion fallback). Grows from its held tip (origin near
   the bottom) so it reads as "popping up". */
.op-confetti-horn {
  position: absolute; left: 0; top: 0;
  width: var(--horn-size, 30px); height: auto;
  transform: translate(-50%, -55%) scale(0.4) rotate(var(--horn-rot, 0deg));
  transform-origin: 50% 88%;
  opacity: 0;
}
.op-horn-cone   { fill: #57c4ae; stroke: #2f9e86; stroke-width: 2; stroke-linejoin: round; }
.op-horn-mouth  { fill: rgba(150, 255, 240, 0.95); stroke: #2f9e86; stroke-width: 1.4; }
.op-horn-stripe { fill: none; stroke: #2f9e86; stroke-width: 2.4; stroke-linecap: round; opacity: 0.7; }

/* One confetti particle. Seafoam shade (--c), size (--sz), shape (--rad) and
   flight vector (--dx/--dy/--rot/--dur) are all set inline per particle by JS.
   Invisible until the burst animation drives it. */
.op-confetti-bit {
  position: absolute; left: 0; top: 0;
  width: var(--sz, 6px); height: var(--sz, 6px);
  background: var(--c, var(--glow-green));
  border-radius: var(--rad, 1px);
  opacity: 0;
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
}

.op-confetti.is-blasting .op-confetti-horn {
  animation: op-horn-pop var(--horn-dur, 1.55s) cubic-bezier(.2,.85,.25,1) forwards;
}
.op-confetti.is-pop .op-confetti-horn {
  animation: op-horn-soft 1s ease forwards;
}
.op-confetti.is-blasting .op-confetti-bit {
  animation: op-bit var(--dur, 1.2s) cubic-bezier(.12,.62,.3,1) forwards;
}
@keyframes op-horn-pop {
  0%   { opacity: 0; transform: translate(-50%,-55%) scale(0.3)  rotate(calc(var(--horn-rot, 0deg) - 10deg)); }
  20%  { opacity: 1; transform: translate(-50%,-55%) scale(1.08) rotate(calc(var(--horn-rot, 0deg) + 3deg)); }
  38%  {             transform: translate(-50%,-55%) scale(1)    rotate(var(--horn-rot, 0deg)); }
  76%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%,-55%) scale(1)    rotate(var(--horn-rot, 0deg)); }
}
@keyframes op-horn-soft {
  0%   { opacity: 0; transform: translate(-50%,-55%) scale(0.8) rotate(var(--horn-rot, 0deg)); }
  30%  { opacity: 1; transform: translate(-50%,-55%) scale(1)   rotate(var(--horn-rot, 0deg)); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%,-55%) scale(1)   rotate(var(--horn-rot, 0deg)); }
}
@keyframes op-bit {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.5) rotate(0deg); }
  12%  { opacity: 1; }
  72%  { opacity: 1; }
  100% { opacity: 0;
         transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px)))
                    scale(1) rotate(var(--rot, 0deg)); }
}
/* Safety net: even if a burst is somehow triggered, respect reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .op-confetti.is-blasting .op-confetti-bit { animation: none; opacity: 0; }
}

/* ---- pin-line diagram (SVG overlays the wordmark box) ------------- */
/* The SVG uses the wordmark's OWN coordinate space (viewBox 0 0 2000 900:
   the 2000x516 source image + 384u of headroom below for the drop+arms).
   preserveAspectRatio xMidYMin keeps it locked to the top-centre of the
   wordmark, so the drawn origin sits exactly on the measured "i" dot.
   The SVG box is 2000x900 => its rendered height = width * (900/2000),
   and it starts at the wordmark's top-left. */
.op-pins {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;                    /* pins stay above the mark */
  width: 100%;
  height: auto;                  /* height follows aspect ratio of viewBox */
  overflow: visible;
  pointer-events: none;          /* SVG passes clicks through by default... */
}
/* ...except the invisible hit-paths, which opt back in so hovering the
   actual pin line lights its side (the visible hairline stays inert). */
.op-pins .op-pin-hit { pointer-events: stroke; }
.op-pins .op-pin-line { pointer-events: none; }

.op-pin-line {
  fill: none;
  stroke: var(--pin-color);
  stroke-width: var(--pin-weight);
  stroke-linecap: butt;
  stroke-linejoin: miter;        /* sharp architectural corners */
  shape-rendering: geometricPrecision; /* AA both lines identically => equal weight (crispEdges snapped them unevenly) */
  vector-effect: non-scaling-stroke;
  transition: stroke 0.3s ease, filter 0.3s ease, opacity 0.5s ease;
}

/* Invisible wide hit-paths make the 1px hairlines comfortable to hover.
   They alone take pointer events inside the otherwise pass-through SVG. */
.op-pin-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 28px;            /* generous hover corridor along the line */
  vector-effect: non-scaling-stroke;
  pointer-events: stroke;
  cursor: pointer;
}

/* Active pin line (hover only): KEEP the black stroke, add a neon hologram
   halo around it (Josh 2026-07-05 — supersedes the old recolour-only rule).
   Small blur so it reads as a glow, not a thicker line; the stroke itself
   stays black at a constant 1px. */
.op-composition[data-hover="empower"] .op-pin--left {
  filter: drop-shadow(0 0 1.5px var(--glow-green)) drop-shadow(0 0 3px var(--glow-green));
}
.op-composition[data-hover="build"] .op-pin--right {
  filter: drop-shadow(0 0 1.5px var(--build-hi)) drop-shadow(0 0 3px var(--build-hi));
}

/* Labels live in normal DOM (not SVG) so type rendering matches the site.
   Each sits at the far end of its arm, positioned relative to composition. */
.op-label {
  position: absolute;
  z-index: 3;                    /* above the mark */
  font-size: 15px;               /* >= 13px floor, comfortably readable */
  letter-spacing: 0.01em;
  line-height: 1;
  text-decoration: none;
  color: var(--op-muted);
  white-space: nowrap;
  pointer-events: auto;
  transition: color 0.4s ease, opacity 0.4s ease;   /* softer fade in/out */
  opacity: 0.85;
}
.op-label:hover,
.op-label:focus-visible {
  color: var(--op-ink);          /* quiet darken on hover */
  opacity: 1;
  outline: none;
}
/* When a side is hovered, keep its label dark and add the neon hologram glow —
   same treatment as the wordmark, pins, and offerings, so the whole door reads
   as one black group lighting up. Hover only (no persistent data-side). */
.op-composition[data-hover="empower"] .op-label--left {
  color: var(--op-ink);
  opacity: 1;
  text-shadow: 0 0 5px var(--glow-green), 0 0 12px var(--glow-green);
}
.op-composition[data-hover="build"] .op-label--right {
  color: var(--op-ink);
  opacity: 1;
  text-shadow: 0 0 5px var(--build-hi), 0 0 12px var(--build-hi);
}
/* keep a soft focus ring for keyboard users only */
.op-label:focus-visible {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

/* Arm endpoints (in SVG units) mapped to composition offsets.
   Left arm end  = (254, 990)  -> right edge of the 'empower me' label.
   Right arm end = (1799, 990) -> left edge of the 'Build me' label.
   y offset = 990/2000 * --op-w  (SVG box is 2000 wide). */
.op-label--left {
  text-align: right;
  right: calc((2000 - 254) / 2000 * var(--op-w) + var(--pin-label-gap));
  top:   calc(990 / 2000 * var(--op-w));
  transform: translateY(-50%);   /* centre the label on the arm line */
}
.op-label--right {
  text-align: left;
  left: calc(1799 / 2000 * var(--op-w) + var(--pin-label-gap));
  top:  calc(990 / 2000 * var(--op-w));
  transform: translateY(-50%);
}

/* ---- "specialist" lockup line, centred under the t-d-o span ---------- */
.op-specialist {
  position: absolute;
  z-index: 3;
  left: calc(1554.5 / 2000 * var(--op-w) - 3px);   /* centre of t-d-o, nudged 3px left */
  top:  calc(365 / 2000 * var(--op-w) - 4px); /* nook beside the i, under tdo (dropped 10px) */
  transform: translateX(-50%);
  color: var(--op-mark-green);                /* the logo's own letter-green */
  font-family: "Stardos Stencil", var(--op-font);  /* Josh's pick for this word */
  font-weight: 700;
  font-size: calc(150 / 2000 * var(--op-w));  /* 50% larger; scales with the wordmark */
  letter-spacing: 0.06em;
  line-height: 1;
  white-space: nowrap;
  pointer-events: none;
}

/* ---- the input CENTERED under "tdo" (right portion of the wordmark) -- */
/* Measured 'tdo' spans x1114 (t) -> x1995 (mark right edge); centre =
   (1114+1995)/2 = 1554.5/2000 = 77.7%. The field is centred on that point
   and its own text is centred, so "What do you need built?" sits directly
   under t-d-o, sitting directly BELOW the tdo letters (y~590), not down by the arms. */
/* Comms input — centred UNDER the pin-line's 90-degree corner (~50.5% =
   i-stem), sitting just below the horizontal arms (y=990 in the 2000u space). */
.op-inputwrap {
  position: absolute;
  z-index: 5;                    /* foreground: the reveal menu sits over all else */
  left: 50.5%;                                    /* centred on the corner / i-stem */
  top:  calc(990 / 2000 * var(--op-w) + 62px);    /* dropped clear below the pin line */
  transform: translateX(-50%);                    /* centre the field on the corner */
  width: min(320px, 82vw);
  min-width: 220px;
  transition: opacity 0.3s ease;                  /* fades out when a door opens */
}
/* When a door is open its menu owns the space — the centred input steps aside
   (like the door's own label does) so it never overlaps the item text. The JS
   freezes the intro op-rise animation after it plays, otherwise its `both` fill
   would pin opacity:1 and block this hide. */
.op-composition.is-open-empower .op-inputwrap,
.op-composition.is-open-build   .op-inputwrap {
  opacity: 0;
  pointer-events: none;
}
.op-input {
  width: 100%;
  padding: 0.6rem 0.9rem;
  font: inherit;
  font-size: 15px;
  text-align: center;            /* placeholder/text centred under the corner */
  color: var(--op-ink);
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid rgba(18, 53, 40, 0.18);
  border-radius: 999px;          /* soft pill — reads as "type here" */
  cursor: text;
  transition: border-color 0.24s ease, background 0.24s ease, box-shadow 0.24s ease;
}
.op-input::placeholder { color: var(--op-muted); opacity: 0.95; }
.op-input:hover {
  border-color: rgba(18, 53, 40, 0.32);
  background: #fff;
}
.op-input:focus {
  outline: none;
  border-color: var(--op-ink);
  background: #fff;
  box-shadow: 0 6px 20px -10px rgba(18, 53, 40, 0.45);
}

/* The comms menu is sealed inside .op-composition's stacking context (isolate),
   which paints BELOW the fixed z-index:4 .op-sub-wrap — so Subscription Hunter
   would paint over the menu. While the menu is open, lift the whole composition
   above the sub link so the menu (the thing being used) covers it cleanly.
   Scoped to is-live so normal stacking is untouched. */
body:has(.op-inputwrap.is-live) .op-composition { z-index: 5; }

/* ---- the three send options, revealed on focus/typing --------------- */
/* Hidden at rest (blur + fade + inert); the .is-live class on the wrap fades
   them in, matching the page's blur-reveal language. visibility:hidden also
   keeps the buttons out of the tab order until the menu is open. */
.op-comms-actions {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  width: max-content;
  min-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px;
  background: #ffffff;              /* solid: fully COVERS Subscription Hunter behind it */
  border: 1px solid rgba(18, 53, 40, 0.10);
  border-radius: 14px;
  box-shadow: 0 16px 34px -14px rgba(18, 53, 40, 0.4);
  opacity: 0;
  visibility: hidden;
  filter: blur(6px);
  pointer-events: none;
  transition: opacity 0.28s ease, filter 0.28s ease, transform 0.28s ease,
              visibility 0s linear 0.28s;
}
.op-inputwrap.is-live .op-comms-actions {
  opacity: 1;
  visibility: visible;
  filter: blur(0);
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
  transition: opacity 0.28s ease, filter 0.28s ease, transform 0.28s ease,
              visibility 0s;
}
.op-comms-btn {
  display: block;
  width: 100%;
  text-align: center;
  padding: 0.5rem 0.9rem;
  font: inherit;
  color: var(--op-ink);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease;
}
.op-comms-btn:hover,
.op-comms-btn:focus-visible {
  background: var(--op-warm);
  border-color: rgba(18, 53, 40, 0.16);
  outline: none;
}
.op-comms-btn__label { display: block; font-size: 15px; font-weight: 500; }
.op-comms-btn__hint  { display: block; font-size: 13px; color: var(--op-muted); margin-top: 1px; }

/* ---- responsive: keep it top-aligned & un-scrolled on small screens --- */
@media (max-width: 560px) {
  :root {
    --pin-drop: 58px;
    --pin-arm: 96px;
  }
  .op-composition { transform: translateY(15vh); }
}

/* Narrow screens: the level-2 title-BESIDE-body row starves the sub-item
   column (the panel is only ~46vw), so the real copy wraps into a very tall
   sliver that can reach the fixed mission line at the bottom. Stack the title
   ABOVE the body here so the text gets the full panel width and the block
   stays short. Roomier screens keep the intended beside-layout. */
@media (max-width: 640px) {
  .op-l2row,
  .op-reveal--build .op-l2row { flex-direction: column; gap: 0.7em; }
  .op-reveal--empower .op-l2row { align-items: flex-start; }
  .op-reveal--build   .op-l2row { align-items: flex-end; }   /* keep Build right-aligned */
  .op-sub-title { margin: 0 0 0.5em; }
}

/* ---- motion: a quiet settle, matched to the live site ------------- */
/* IMPORTANT: the rise animates the `translate` LONGHAND, not `transform`.
   Several elements here (labels, input, and any future tweak) rely on their
   own `transform` for positioning (translateX/Y -50% centring). `translate`
   is an independent property that COMPOSES with `transform`, so the intro
   rise no longer clobbers that centring. `op-rise` (opacity+translate) is for
   the visible elements; `op-glow-rise` (translate only) keeps the glow layers
   pixel-aligned to the mark while their opacity stays owned by hover/select. */
@media (prefers-reduced-motion: no-preference) {
  .op-pins,
  .op-label,
  .op-inputwrap {
    animation: op-rise 0.7s cubic-bezier(.2,.8,.2,1) both;
  }
  /* One fluid load-in. Both layers LIFT together (shared translate) while the 3D
     fades in and then dissolves straight into the flat. The crossfade OVERLAPS the
     lift — the mark is still settling as it morphs — so it reads as a single,
     near-linear, connected motion instead of "lift, settle, then separately fade". */
  .op-mark--3d {
    animation: op-lift 1.9s cubic-bezier(.33,.45,.25,1) 0.05s both,
               op-3d-fade 1.9s linear 0.05s both;
  }
  .op-mark--flat {
    animation: op-lift 1.9s cubic-bezier(.33,.45,.25,1) 0.05s both,
               op-flat-fade 1.9s linear 0.05s both;
  }
  @keyframes op-lift      { from { translate: 0 14px; } to { translate: 0 0; } }
  @keyframes op-3d-fade   { 0% { opacity: 0; } 16% { opacity: 1; } 40% { opacity: 1; } 100% { opacity: 0; } }
  @keyframes op-flat-fade { 0% { opacity: 0; } 40% { opacity: 0; } 100% { opacity: 1; } }
  .op-pins      { animation-delay: 0.28s; }
  .op-label     { animation-delay: 0.40s; }
  .op-inputwrap { animation-delay: 0.50s; }
  @keyframes op-rise {
    from { opacity: 0; translate: 0 12px; }
    to   { opacity: 1; translate: 0 0; }
  }

  /* The glow overlays ride the mark's rise EXACTLY (same 12px travel, same
     timing/delay) so they stay pixel-aligned to it the entire intro. Translate
     only — opacity stays governed by the hover/select rules (they must remain
     invisible until a side lights). */
  .op-glow {
    animation: op-glow-rise 0.7s cubic-bezier(.2,.8,.2,1) 0.02s both;
  }
  @keyframes op-glow-rise {
    from { translate: 0 12px; }
    to   { translate: 0 0; }
  }
}

/* ============================================================
   LEVEL 3 — the booking surface (day -> time -> form -> done)
   Opens IN the active side's column (the recursion's third level). Nothing here
   overlaps anything else: while a side is open its opposite door + the centre
   input are hidden, and the surface scrolls INTERNALLY before it could ever reach
   the fixed mission line at the bottom. Text floors honoured (chips/inputs
   14-15px, labels 13px). All spacing/colour lives in knobs, tuned by eye.
   ============================================================ */
:root {
  --book-inset: 2rem;          /* how far the booking panel sits from the screen edge */
  --book-maxw: 32rem;          /* booking panel max width */
  --book-gap: 0.5rem;          /* gap between day / time chips */
  --book-lift: -1.5rem;        /* gentle lift toward the wordmark (less than L2's) */
  /* Internal-scroll cap: derived from the panel's own top (which tracks --op-w)
     so the surface always ends above the bottom mission line, on any height. */
  --book-surface-maxh: calc(85vh - 0.495 * var(--op-w) - 2rem);
  --book-accent-empower: #2f9e86;   /* Empower seafoam (matches the door) */
  --book-accent-build:   #b5872b;   /* Build gold (readable-on-white member of --build-hi) */
}

/* Booking gives the side panel an explicit, comfortable width (not shrink-to-fit)
   and re-anchors it to a safe screen-edge inset so the form + chips have room and
   read consistently across steps — down to ~400px (overrides L1/L2 anchoring). */
.op-reveal.is-booking {
  width:     min(var(--book-maxw), calc(100vw - 2 * var(--book-inset)));
  max-width: min(var(--book-maxw), calc(100vw - 2 * var(--book-inset)));
}
.op-reveal--empower.is-booking { left:  calc(var(--book-inset) - (100vw - var(--op-w)) / 2); }
.op-reveal--build.is-booking   { right: calc(var(--book-inset) - (100vw - var(--op-w)) / 2); }

.op-level.is-booking { transform: translateY(var(--book-lift)); }
.op-book-surface {
  max-height: var(--book-surface-maxh);
  overflow-y: auto;
  padding-bottom: 2px;
  opacity: 0;                        /* blur-in, matched to the site's reveal language */
  filter: blur(4px);
  transition: opacity 500ms ease, filter 500ms ease;
}
.op-level.is-in .op-book-surface { opacity: 1; filter: blur(0); }
.op-reveal--build .op-book-surface { margin-left: auto; }   /* hug the right edge on Build */

/* interactive bits opt back into pointer events (the panel is pointer-events:none) */
.op-book-chip, .op-book-input, .op-book-submit { pointer-events: auto; }
.op-book-input { -webkit-user-select: text; user-select: text; }

.op-book-title      { font-weight: 600; font-size: clamp(16px, 1.8vw, 19px); color: var(--op-ink); margin: 0 0 0.15em; }
.op-book-intro      { font-size: clamp(13px, 1.3vw, 14px); line-height: 1.5; color: var(--op-muted); margin: 0 0 0.9em; max-width: 24em; }
.op-reveal--build .op-book-intro { margin-left: auto; }
.op-book-step-label { font-size: 13px; font-weight: 600; letter-spacing: 0.01em; color: var(--op-muted); margin: 0.2em 0 0.55em; }
.op-book-status     { font-size: 13.5px; color: var(--op-muted); margin: 0.5em 0; }

/* day / time chips: soft pills that wrap; side-tinted focus ring */
.op-book-list { display: flex; flex-wrap: wrap; gap: var(--book-gap); margin: 0.1em 0 0; }
.op-reveal--build .op-book-list { justify-content: flex-end; }
.op-book-chip {
  font: inherit; font-size: 14px; font-weight: 500; white-space: nowrap;
  color: var(--op-ink); background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(18, 53, 40, 0.16); border-radius: 999px;
  padding: 0.4rem 0.85rem; cursor: pointer;
  transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
}
.op-book-chip:hover, .op-book-chip:focus-visible { outline: none; background: #fff; }
.op-reveal--empower .op-book-chip:hover, .op-reveal--empower .op-book-chip:focus-visible {
  border-color: var(--book-accent-empower); box-shadow: 0 0 0 3px rgba(47, 158, 134, 0.14);
}
.op-reveal--build .op-book-chip:hover, .op-reveal--build .op-book-chip:focus-visible {
  border-color: var(--book-accent-build); box-shadow: 0 0 0 3px rgba(181, 135, 43, 0.16);
}
.op-book-tz { font-size: 13px; color: var(--op-muted); margin: 0.8em 0 0; }

/* the details form */
.op-book-form  { display: flex; flex-direction: column; gap: 0.6rem; max-width: 22rem; margin-top: 0.15rem; }
.op-reveal--build .op-book-form { margin-left: auto; }
.op-book-field { display: flex; flex-direction: column; gap: 0.2rem; }
.op-reveal--build .op-book-field { align-items: flex-end; }
.op-book-label { font-size: 13px; color: var(--op-muted); }
.op-book-input {
  width: 100%; font: inherit; font-size: 15px; padding: 0.5rem 0.75rem;
  color: var(--op-ink); background: rgba(255, 255, 255, 0.82);
  border: 1px solid rgba(18, 53, 40, 0.18); border-radius: 12px;
  transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.op-book-input:focus { outline: none; border-color: var(--op-ink); background: #fff; box-shadow: 0 6px 18px -12px rgba(18, 53, 40, 0.5); }
.op-reveal--build .op-book-input { text-align: right; }
.op-book-submit {
  align-self: flex-start; margin-top: 0.3rem; font: inherit; font-weight: 600; font-size: 15px;
  color: #fff; border: 0; border-radius: 999px; padding: 0.55rem 1.15rem; cursor: pointer;
  transition: filter .16s ease, opacity .16s ease;
}
.op-reveal--empower .op-book-submit { background: var(--book-accent-empower); }
.op-reveal--build   .op-book-submit { background: var(--book-accent-build); align-self: flex-end; }
.op-book-submit:hover { filter: brightness(1.05); }
.op-book-submit:disabled { opacity: 0.6; cursor: default; }

.op-book-error { font-size: 13.5px; line-height: 1.45; color: #b06a5c; margin: 0.2em 0 0; max-width: 22em; }  /* gentle, not alarming */
.op-reveal--build .op-book-error { margin-left: auto; text-align: right; }

/* the confirmed state */
.op-book-done-title { font-weight: 600; font-size: clamp(16px, 1.8vw, 19px); color: var(--op-ink); margin: 0 0 0.3em; }
.op-book-done-msg   { font-size: 14px; line-height: 1.55; color: var(--l2-sub-color, #34473e); max-width: 24em; margin: 0; }
.op-reveal--build .op-book-done-msg { margin-left: auto; }
.op-book-done-slot  { font-weight: 600; color: var(--op-ink); }

@media (prefers-reduced-motion: reduce) {
  .op-book-surface { filter: none; transition: none; }
}

/* While the booking surface is open, the bottom mission recedes — the same
   "secondary chrome steps aside when you commit to a door" move the centre input
   already makes. This guarantees the taller booking surface can never collide
   with the mission line (incl. its hover-reveal) on short/narrow viewports. Only
   booking triggers it; the short L1/L2 screens keep the mission in view. */
body:has(.op-reveal.is-booking) .op-sub-wrap {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

/* Narrow screens: more room, drop the lift so the surface has vertical breathing. */
@media (max-width: 640px) {
  :root { --book-inset: 1.1rem; }
  .op-level.is-booking { transform: none; }
}
