/* ═══════════════════════════════════════════════════════════════
   RSVP Code Finder — /Rsvp/Seminar, and /Rsvp/Seminar/{code} when the code matches no visible event.
   Markup + copy: Pages/Rsvp/_CodeFinder.cshtml · Motion: wwwroot/js/rsvp-find.js

   Public and mobile-first, in the RSVP family (rsvp-recovery.css / rsvp-confirmation.css): indigo #2c2d7f,
   Source Sans Pro, plus Source Code Pro for the code itself.

   This file owns resting geometry, state colour and the CSS-only ambient loops. Choreographed motion
   (intro, reels, shake, lock-in, wipe) is written frame by frame by rsvp-find.js as inline `transform` /
   `translate` / `opacity`. The ambient loops animate the separate `rotate` / `scale` properties, so the
   two never fight over one property.

   Colour budget. Each hue has one meaning here:
     indigo  — the brand: the one solid button, and the hand-off wipe
     amber   — a code that didn't match (transient: clears as soon as the visitor edits)
     green   — a code that matched
   The scenery is indigo tint and hairline only, so semantic colour always reads as the loudest thing.
   ═══════════════════════════════════════════════════════════════ */

/* :host as well as :root: What's New embeds an excerpt of this page in a shadow root (which has no :root), linking
   this same file, so the excerpt reads the same tokens. On the page itself :host matches nothing. */
:root,
:host {
    --cf-paper: #f6f5fb;
    --cf-ink: #1d1b4f;
    --cf-ink-2: #45436b;
    --cf-ink-3: #64628a;
    --cf-indigo: #2c2d7f;
    --cf-indigo-deep: #23246a;
    --cf-tint-1: #eae9f8;
    --cf-tint-2: #dfddf4;
    --cf-hair: rgba(44, 45, 127, 0.15);
    --cf-hair-strong: rgba(44, 45, 127, 0.3);
    --cf-amber: #f2a23a;
    --cf-amber-ink: #8a5300;
    --cf-amber-tint: #fff5e4;
    --cf-green: #2a9d5c;
    --cf-green-ink: #17703d;
    --cf-green-tint: #e9f6ee;
    --cf-shadow: 0 1px 0 rgba(44, 45, 127, 0.05), 0 14px 28px -16px rgba(44, 45, 127, 0.38);
    --cf-sans: 'Source Sans Pro', -apple-system, 'Segoe UI', Roboto, sans-serif;
    --cf-mono: 'Source Code Pro', ui-monospace, 'Cascadia Mono', Menlo, monospace;
    --cf-radius: 14px;
}

html,
body {
    margin: 0;
    min-height: 100%;
    background: var(--cf-paper);
}

body {
    font-family: var(--cf-sans);
    color: var(--cf-ink);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Frame 0 is drawn by script; until then the animated pieces wait (see the head script for the failsafe). */
.cf-boot [data-cf-intro],
.cf-boot [data-cf-status],
.cf-boot [data-cf-tips] {
    opacity: 0;
}


/* ── Stage ─────────────────────────────────────────────────────── */

.cf-stage {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    /* minmax(0, 1fr): the track is bounded by the stage, so the panel's max-width: 100% can actually bite
       (an auto track would grow to the panel's 40rem and the max-width would resolve against itself). */
    grid-template-columns: minmax(0, 1fr);
    place-items: center;
    padding: clamp(2rem, 6vh, 4.5rem) 1.25rem clamp(2.5rem, 8vh, 5rem);
    overflow: hidden;
    isolation: isolate;
}


/* ── Scenery ───────────────────────────────────────────────────── */

.cf-art {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    pointer-events: none;
}

.cf-layer {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

.cf-shape {
    position: absolute;
    display: block;
}

.cf-disc {
    width: 66vmin;
    height: 66vmin;
    left: -17vmin;
    bottom: -27vmin;
    border-radius: 50%;
    background: var(--cf-tint-1);
}

.cf-half {
    width: 32vmin;
    height: 16vmin;
    right: 11vw;
    top: 0;
    border-radius: 0 0 32vmin 32vmin;
    background: var(--cf-tint-2);
    transform-origin: 50% 0;
}

/* Stroke widths below are in SVG user units, NOT vector-effect: non-scaling-stroke. Chrome applies a
   pathLength-normalized dash pattern in the wrong space when non-scaling-stroke is on, so the draw-in
   (stroke-dasharray: 1 + dashoffset) stopped short and left a gap in the ring. */
.cf-arcs {
    width: 34vmin;
    height: 34vmin;
    right: 0;
    bottom: 0;
    fill: none;
    stroke: var(--cf-hair-strong);
    stroke-width: 1;
    stroke-linecap: round;
}

.cf-arcs path {
    stroke-dasharray: 1;
}

.cf-rule {
    left: 0;
    top: 66vh;
    width: 21vw;
    height: 1.5px;
    background: var(--cf-hair-strong);
    transform-origin: 0 50%;
}

.cf-ring,
.cf-orbit {
    width: 42vmin;
    height: 42vmin;
    right: -10vmin;
    top: 20vh;
}

.cf-ring {
    fill: none;
    stroke: var(--cf-hair-strong);
    stroke-width: 0.4;
    overflow: visible;
}

.cf-ring circle {
    stroke-dasharray: 1;
}

.cf-orbit-dot {
    position: absolute;
    left: 50%;
    top: 0;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border-radius: 50%;
    background: var(--cf-indigo);
    box-shadow: 0 0 0 6px rgba(44, 45, 127, 0.1);
}

.cf-dots {
    left: 7vw;
    top: 13vh;
    display: grid;
    grid-template-columns: repeat(7, 6px);
    gap: 14px;
}

.cf-dots i {
    display: block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgba(44, 45, 127, 0.22);
}

/* Crosshair marks: abstract scenery only. They carry no meaning about how the visitor heard of the event. */
.cf-mark {
    width: 18px;
    height: 18px;
}

.cf-mark::before,
.cf-mark::after {
    content: '';
    position: absolute;
    background: var(--cf-hair-strong);
    border-radius: 1px;
}

.cf-mark::before {
    left: 8.25px;
    top: 0;
    width: 1.5px;
    height: 18px;
}

.cf-mark::after {
    left: 0;
    top: 8.25px;
    width: 18px;
    height: 1.5px;
}

.cf-mark-a { left: 21vw; top: 76vh; }
.cf-mark-b { right: 27vw; top: 11vh; }
.cf-mark-c { right: 13vw; bottom: 13vh; }

/* Ambient loops: start once the intro has landed (.is-ambient), only for visitors who are fine with motion. */
@media (prefers-reduced-motion: no-preference) {
    .is-ambient .cf-orbit {
        animation: cf-orbit 28s linear infinite;
    }

    .is-ambient .cf-disc {
        animation: cf-breathe 14s ease-in-out infinite;
    }

    .is-ambient .cf-half {
        animation: cf-sway 18s ease-in-out infinite;
    }
}

@keyframes cf-orbit {
    from { rotate: 0deg; }
    to { rotate: 360deg; }
}

@keyframes cf-breathe {
    0%, 100% { scale: 1; }
    50% { scale: 1.035; }
}

@keyframes cf-sway {
    0%, 100% { rotate: 0deg; }
    50% { rotate: -5deg; }
}


/* ── Panel ─────────────────────────────────────────────────────── */

.cf-panel {
    position: relative;
    width: 40rem;
    max-width: 100%;
    text-align: center;
}

.cf-badge {
    display: inline-grid;
    place-items: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: #fff;
    box-shadow: inset 0 0 0 1px var(--cf-hair), var(--cf-shadow);
    margin-bottom: 1.5rem;
}

.cf-badge svg {
    width: 30px;
    height: 30px;
    fill: none;
    stroke: var(--cf-indigo);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.cf-badge svg > * {
    stroke-dasharray: 1;
}

.cf-title {
    margin: 0;
    font-size: clamp(2.375rem, 1.45rem + 3.6vw, 3.875rem);
    line-height: 1.04;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--cf-ink);
}

/* Each word rises out of its own mask. The padding/negative margin pair gives descenders room inside it. */
.cf-word {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
    padding: 0 0.04em 0.14em;
    margin: 0 -0.04em -0.14em;
}

.cf-word > span {
    display: inline-block;
    transform-origin: 0 100%;
}

.cf-word-accent {
    color: var(--cf-indigo);
}

.cf-lede {
    margin: 1rem auto 0;
    max-width: 30rem;
    font-size: 1.1875rem;
    line-height: 1.5;
    color: var(--cf-ink-2);
    text-wrap: balance;
}


/* ── The code field ────────────────────────────────────────────── */

.cf-form {
    margin-top: 2.25rem;
}

.cf-label {
    display: block;
    margin-bottom: 0.75rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--cf-ink-2);
}

.cf-field {
    position: relative;
    display: flex;
    justify-content: center;
}

/* Without script this is a plain, generous text field; .cf-live (added by rsvp-find.js) turns it into the tiles. */
.cf-input {
    display: block;
    width: 18rem;
    max-width: 100%;
    height: 4.5rem;
    padding: 0 1rem;
    border: 0;
    border-radius: var(--cf-radius);
    background: #fff;
    box-shadow: inset 0 0 0 1.5px var(--cf-hair-strong), var(--cf-shadow);
    font: 600 2rem/1 var(--cf-mono);
    color: var(--cf-ink);
    text-align: center;
    text-transform: uppercase;
    outline: none;
}

.cf-input:focus {
    box-shadow: inset 0 0 0 2px var(--cf-indigo), 0 0 0 4px rgba(44, 45, 127, 0.12), var(--cf-shadow);
}

.cf-field.is-miss .cf-input {
    box-shadow: inset 0 0 0 2px var(--cf-amber), var(--cf-shadow);
    background: var(--cf-amber-tint);
}

.cf-tiles {
    display: none;
}

/* Live mode: the field hugs the tile row, and the real input lies invisibly over it, so taps focus it natively
   (and raise the phone keyboard). 16px keeps iOS from zooming on focus. */
.cf-live .cf-field {
    width: -webkit-fit-content;
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
}

.cf-live .cf-input {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    opacity: 0;
    font-size: 16px;
    cursor: text;
    z-index: 2;
}

.cf-live .cf-tiles {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    /* The row keeps the default tile height when longer codes step the tiles down a size; the panel is
       vertically centred, so a shorter row would nudge the whole page up as the visitor types. */
    min-height: var(--cf-row-h, 6.5rem);
    gap: var(--cf-gap);
    --cf-tw: 5.25rem;
    --cf-th: 6.5rem;
    --cf-tf: 3rem;
    --cf-gap: 0.875rem;
}

/* Named size variants. The row is at least four boxes (generated codes are 4 characters) and grows one box
   per character beyond that, up to 10 in practice. The script picks a variant from boxes + 1 (the "+"
   marker's share, counted even while it's hidden, so focusing or blurring never resizes the tiles).
   Default fits 5. */
.cf-tiles[data-size="7"]    { --cf-tw: 4.5rem;   --cf-th: 5.75rem; --cf-tf: 2.625rem; --cf-gap: 0.75rem; }
.cf-tiles[data-size="9"]    { --cf-tw: 3.75rem;  --cf-th: 5rem;    --cf-tf: 2.25rem;  --cf-gap: 0.625rem; }
.cf-tiles[data-size="11"]   { --cf-tw: 3.125rem; --cf-th: 4.25rem; --cf-tf: 1.875rem; --cf-gap: 0.5rem; }
.cf-tiles[data-size="wrap"] { --cf-tw: 2.75rem;  --cf-th: 3.75rem; --cf-tf: 1.625rem; --cf-gap: 0.5rem; max-width: 30rem; }

.cf-tile {
    position: relative;
    flex: 0 0 auto;
    width: var(--cf-tw);
    height: var(--cf-th);
    transform-origin: 0 0;
}

.cf-tile-face {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border-radius: var(--cf-radius);
    background: #fff;
    box-shadow: inset 0 0 0 1.5px var(--cf-hair), var(--cf-shadow);
    transition: box-shadow 0.18s ease, background-color 0.18s ease;
}

.cf-reel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: hidden;
    border-radius: inherit;
}

.cf-strip {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    will-change: transform;
}

.cf-strip > span {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    height: var(--cf-th);
    font: 600 var(--cf-tf)/1 var(--cf-mono);
    color: var(--cf-ink);
}

.cf-tile[hidden] {
    display: none;
}

/* An empty box shows where a character goes (not while glyphs are rolling past it). */
.cf-tile.is-rolling .cf-tile-face::after {
    opacity: 0;
}

.cf-tile.is-empty .cf-tile-face::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 24%;
    width: 30%;
    height: 3px;
    margin-left: -15%;
    border-radius: 2px;
    background: var(--cf-tint-2);
}

.cf-caret {
    position: absolute;
    top: 27%;
    left: 50%;
    width: 2px;
    height: 46%;
    margin-left: -1px;
    border-radius: 1px;
    background: var(--cf-indigo);
    opacity: 0;
    pointer-events: none;
}

.cf-tile.is-active .cf-tile-face {
    box-shadow: inset 0 0 0 2px var(--cf-indigo), 0 0 0 4px rgba(44, 45, 127, 0.12), var(--cf-shadow);
}

/* Caret in an empty box: centred. */
.cf-tile.is-active.is-empty .cf-caret {
    opacity: 1;
    animation: cf-blink 1.06s steps(1) infinite;
}

/* Caret between characters: sits at the tile's leading edge. */
.cf-tile.is-active:not(.is-empty):not(.cf-more) .cf-caret {
    left: 9%;
    opacity: 1;
    animation: cf-blink 1.06s steps(1) infinite;
}

/* Caret after the last character: once the four boxes are full (the "+" marker then lights up), or at the
   maximum length. */
.cf-tile.is-caret-after .cf-caret {
    left: auto;
    right: 7%;
    opacity: 1;
    animation: cf-blink 1.06s steps(1) infinite;
}

.cf-tile.is-caret-after .cf-tile-face {
    box-shadow: inset 0 0 0 2px var(--cf-indigo), 0 0 0 4px rgba(44, 45, 127, 0.12), var(--cf-shadow);
}

.cf-tile.is-selected .cf-tile-face {
    background: var(--cf-tint-1);
    box-shadow: inset 0 0 0 2px var(--cf-indigo), var(--cf-shadow);
}

@keyframes cf-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0; }
}

/* The "+" marker after the last box: more characters are allowed. A half-width dashed pill with a plus. It
   never becomes an empty box, because most codes are exactly 4 characters and an empty 5th box would read as
   "one is missing". Once the four are full and the caret is at the end (the caret then sits after the last
   character), the marker is "ready": indigo, with a slow pulse on the plus. Typing a 5th character deals a
   new box out of it, and the marker slides on. */
.cf-more {
    width: calc(var(--cf-tw) * 0.5);
}

.cf-more .cf-tile-face {
    background: rgba(255, 255, 255, 0.55);
    box-shadow: none;
    border: 1.5px dashed var(--cf-hair-strong);
}

.cf-more.is-active .cf-tile-face {
    background: #fff;
    border-color: var(--cf-indigo);
    box-shadow: 0 0 0 4px rgba(44, 45, 127, 0.1);
}

.cf-more-plus {
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(var(--cf-tw) * 0.28);
    height: calc(var(--cf-tw) * 0.28);
    margin: calc(var(--cf-tw) * -0.14) 0 0 calc(var(--cf-tw) * -0.14);
    fill: none;
    stroke: var(--cf-ink-3);
    stroke-width: 2;
    stroke-linecap: round;
    transition: stroke 0.18s ease;
}

.cf-more.is-active .cf-more-plus {
    stroke: var(--cf-indigo);
}

@media (prefers-reduced-motion: no-preference) {
    .cf-more.is-active .cf-more-plus {
        animation: cf-more-pulse 1.8s ease-in-out infinite;
    }
}

@keyframes cf-more-pulse {
    0%, 100% { scale: 1; }
    50% { scale: 1.18; }
}

/* With tips showing on a miss, the fine print gets a little more air below them. */
.cf-tips:not([hidden]) + .cf-hint {
    margin-top: 1.75rem;
}

/* Miss: amber outline + wash on the characters. Transient — the script drops .is-miss as soon as the
   visitor edits. */
.cf-field.is-miss .cf-tile:not(.cf-more):not(.is-empty) .cf-tile-face {
    background: var(--cf-amber-tint);
    box-shadow: inset 0 0 0 2px var(--cf-amber), var(--cf-shadow);
}

/* Found: each tile stamps green as the script reaches it (.is-locked). */
.cf-tile.is-locked .cf-tile-face {
    background: var(--cf-green-tint);
    box-shadow: inset 0 0 0 2px var(--cf-green), var(--cf-shadow);
}

.cf-tile.is-locked .cf-strip > span {
    color: var(--cf-green-ink);
}

/* Searching: a light sweep crosses the tiles left to right, and signal rings pulse out from the code. */
.cf-field.is-searching .cf-tile-face::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border-radius: inherit;
    background: linear-gradient(100deg, transparent 25%, rgba(44, 45, 127, 0.1) 50%, transparent 75%) no-repeat;
    background-size: 220% 100%;
    animation: cf-sweep 1.1s ease-in-out infinite;
    animation-delay: calc(var(--i, 0) * 70ms);
}

@keyframes cf-sweep {
    from { background-position: 120% 0; }
    to { background-position: -120% 0; }
}

.cf-signal {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    pointer-events: none;
    display: none;
}

.cf-live .cf-signal {
    display: block;
}

.cf-signal i {
    position: absolute;
    top: -6px;
    right: -6px;
    bottom: -6px;
    left: -6px;
    border-radius: 20px;
    box-shadow: inset 0 0 0 1.5px var(--cf-indigo);
    opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
    .cf-field.is-searching .cf-signal i {
        animation: cf-signal 1.5s cubic-bezier(0.2, 0.6, 0.3, 1) infinite;
    }

    .cf-field.is-searching .cf-signal i:nth-child(2) { animation-delay: 0.5s; }
    .cf-field.is-searching .cf-signal i:nth-child(3) { animation-delay: 1s; }
}

/* Mostly sideways: the label sits 12px above the tiles and the rings must stay clear of it. */
@keyframes cf-signal {
    from { transform: scale(1, 1); opacity: 0.4; }
    to { transform: scale(1.1, 1.08); opacity: 0; }
}


/* ── Action + status ───────────────────────────────────────────── */

.cf-actions {
    margin-top: 1.75rem;
}

.cf-submit {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.625rem;
    min-width: 15rem;
    height: 3.5rem;
    padding: 0 1.75rem 0 2rem;
    border: 0;
    border-radius: var(--cf-radius);
    background: var(--cf-indigo);
    color: #fff;
    font: 600 1.1875rem/1 var(--cf-sans);
    cursor: pointer;
    box-shadow: 0 12px 26px -12px rgba(44, 45, 127, 0.7);
    transition: background-color 0.15s ease, transform 0.15s ease;
}

.cf-submit:hover {
    background: var(--cf-indigo-deep);
}

.cf-submit:active {
    transform: translateY(1px);
}

.cf-submit:focus-visible {
    outline: 3px solid rgba(44, 45, 127, 0.35);
    outline-offset: 3px;
}

.cf-submit-arrow {
    width: 1.25rem;
    height: 1.25rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 0.2s ease;
}

.cf-submit:hover .cf-submit-arrow {
    transform: translateX(3px);
}

.cf-submit-spin,
.cf-status-spin {
    display: none;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    animation: cf-spin 0.8s linear infinite;
}

.cf-submit[aria-busy="true"] {
    cursor: progress;
}

.cf-submit[aria-busy="true"] .cf-submit-arrow {
    display: none;
}

.cf-submit[aria-busy="true"] .cf-submit-spin,
.cf-status-spin {
    display: inline-block;
}

@keyframes cf-spin {
    to { transform: rotate(360deg); }
}

/* Reserved height, so a message arriving never shoves the page. */
.cf-status {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 1.75rem;
    margin: 1.25rem 0 0;
    font-size: 1.0625rem;
    line-height: 1.4;
    color: var(--cf-ink-2);
}

.cf-status-icon {
    flex: 0 0 auto;
    width: 1.375rem;
    height: 1.375rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    color: var(--cf-ink-3);
}

.cf-status[data-tone="miss"] .cf-status-icon,
.cf-status[data-tone="error"] .cf-status-icon {
    color: var(--cf-amber);
}

.cf-status[data-tone="miss"],
.cf-status[data-tone="error"] {
    color: var(--cf-amber-ink);
    font-weight: 600;
}

.cf-status[data-tone="found"] {
    color: var(--cf-green-ink);
    font-weight: 600;
}

.cf-status[data-tone="found"] .cf-status-icon {
    color: var(--cf-green);
}

.cf-status-spin {
    width: 1rem;
    height: 1rem;
    color: var(--cf-indigo);
}


/* ── Hint + tips ───────────────────────────────────────────────── */

.cf-hint {
    margin: 1rem auto 0;
    max-width: 28rem;
    font-size: 0.9375rem;
    line-height: 1.5;
    color: var(--cf-ink-3);
    text-wrap: balance;
}

.cf-tips {
    display: grid;
    gap: 0.875rem;
    width: 30rem;
    max-width: 100%;
    margin: 1.75rem auto 0;
    padding: 0;
    list-style: none;
    text-align: left;
}

.cf-hint[hidden],
.cf-tips[hidden] {
    display: none;
}

.cf-tips li {
    display: grid;
    grid-template-columns: 2rem 1fr;
    gap: 0.875rem;
    align-items: start;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--cf-ink-2);
}

.cf-tip-icon {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: #fff;
    box-shadow: inset 0 0 0 1px var(--cf-hair);
}

.cf-tip-icon svg {
    width: 1.0625rem;
    height: 1.0625rem;
    fill: none;
    stroke: var(--cf-ink-2);
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}


/* ── The hand-off wipe ─────────────────────────────────────────── */

.cf-wipe {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 20;
    display: grid;
    place-items: center;
    background: var(--cf-indigo);
    color: #fff;
    -webkit-clip-path: circle(0 at 50% 50%);
    clip-path: circle(0 at 50% 50%);
    visibility: hidden;
}

.cf-wipe.is-on {
    visibility: visible;
}

.cf-wipe-inner {
    display: grid;
    justify-items: center;
    gap: 1.125rem;
    opacity: 0;
}

.cf-wipe-check {
    display: grid;
    place-items: center;
    width: 76px;
    height: 76px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.28);
}

.cf-wipe-check svg {
    width: 36px;
    height: 36px;
    fill: none;
    stroke: #fff;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.cf-wipe-check path {
    stroke-dasharray: 1;
}

.cf-wipe-text {
    font-size: 1.375rem;
    font-weight: 600;
}


/* ── Narrow screens: smaller, quieter scenery and phone-sized tiles ─ */

@media (max-width: 640px) {
    .cf-disc { width: 108vw; height: 108vw; left: -52vw; bottom: -74vw; }
    .cf-half { width: 34vw; height: 17vw; right: 8vw; border-radius: 0 0 34vw 34vw; }
    /* Up in the corner, clear of the headline: a hairline crossing text reads as a defect at phone size. */
    .cf-ring,
    .cf-orbit { width: 56vw; height: 56vw; right: -30vw; top: -24vw; }
    .cf-arcs,
    .cf-dots,
    .cf-rule,
    .cf-mark-a,
    .cf-mark-b { display: none; }
    .cf-mark-c { right: 9vw; bottom: 6vh; }
}

@media (max-width: 480px) {
    .cf-stage {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    .cf-mark-c {
        display: none;
    }

    .cf-lede {
        font-size: 1.125rem;
    }

    /* Phone (~390px, ~358px usable): five tiles at the default size. */
    .cf-live .cf-tiles                   { --cf-tw: 3.75rem;  --cf-th: 4.75rem; --cf-tf: 2.25rem;  --cf-gap: 0.5rem; --cf-row-h: 4.75rem; }
    .cf-live .cf-tiles[data-size="7"]    { --cf-tw: 2.75rem;  --cf-th: 3.75rem; --cf-tf: 1.75rem;  --cf-gap: 0.375rem; }
    .cf-live .cf-tiles[data-size="9"]    { --cf-tw: 2.125rem; --cf-th: 3.125rem; --cf-tf: 1.375rem; --cf-gap: 0.3125rem; }
    .cf-live .cf-tiles[data-size="11"]   { --cf-tw: 1.75rem;  --cf-th: 2.75rem; --cf-tf: 1.125rem; --cf-gap: 0.25rem; }
    .cf-live .cf-tiles[data-size="wrap"] { --cf-tw: 2rem;     --cf-th: 2.75rem; --cf-tf: 1.125rem; --cf-gap: 0.25rem; }

    .cf-tile-face { border-radius: 10px; }

    .cf-submit {
        width: 100%;
        max-width: 22rem;
    }
}

/* Small phones (320px, ~288px usable). */
@media (max-width: 360px) {
    .cf-live .cf-tiles                   { --cf-tw: 3.25rem;  --cf-th: 4.25rem; --cf-tf: 2rem;     --cf-gap: 0.375rem; --cf-row-h: 4.25rem; }
    .cf-live .cf-tiles[data-size="7"]    { --cf-tw: 2.25rem;  --cf-th: 3.25rem; --cf-tf: 1.5rem;   --cf-gap: 0.3125rem; }
    .cf-live .cf-tiles[data-size="9"]    { --cf-tw: 1.75rem;  --cf-th: 2.75rem; --cf-tf: 1.1875rem; --cf-gap: 0.25rem; }
    .cf-live .cf-tiles[data-size="11"]   { --cf-tw: 1.4375rem; --cf-th: 2.375rem; --cf-tf: 1rem;   --cf-gap: 0.1875rem; }
}
