/* ==========================================================================
   Salon studio design system
   - Two themes on one set of tokens: "studio" (the owner's dark workspace, lit by
     the salon's own accent colour) and "public" (the light, salon-branded page).
   - Salon colours arrive from index.html as --primary / --accent / --brand
     (the accent, lifted if needed so it reads on dark) and their --on-* inks.
   - Arabic first: logical properties everywhere, no letter-spacing on Arabic.
   ========================================================================== */

@font-face {
  font-family: 'Readex'; font-style: normal; font-weight: 160 700; font-display: swap;
  src: url(fonts/readex-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
  font-family: 'Readex'; font-style: normal; font-weight: 160 700; font-display: swap;
  src: url(fonts/readex-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Registered so colour changes (palette picks) glide instead of snapping. */
@property --brand { syntax: '<color>'; inherits: true; initial-value: #8b7cff; }
@property --primary { syntax: '<color>'; inherits: true; initial-value: #1f2a37; }
@property --accent { syntax: '<color>'; inherits: true; initial-value: #c8a15a; }
@property --angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

:root {
  --primary: #1f2a37; --on-primary: #fff; --accent: #c8a15a; --on-accent: #111;
  --night: #0a0b10; --accent-lift: #c8a15a; --on-accent-lift: #111;
  --font: 'Readex', system-ui, -apple-system, 'Segoe UI', Tahoma, sans-serif;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --r-xl: 28px; --r-lg: 22px; --r: 16px; --r-sm: 12px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --tabbar: 72px;
  transition: --brand .5s ease, --primary .5s ease, --accent .5s ease;
}

/* ==========================================================================
   Neon Barber (نيون الحلاق): a barbershop at night, lit. Colour is light, not
   paint. Each screen has one light (--light: the studio's violet, or the salon's
   accent on its own pages), and it rims the key surfaces and lights the glyphs,
   the focus ring, the bulbs and the pole.
   - These tokens sit on every themed element with no specificity: each look
     below retunes them, and a subtree with its own data-theme derives its own.
     A subtree that repaints --brand without a data-theme (WP2's launch overlay,
     the landing's .l-painted) must redeclare --light and what derives from it.
   - The landing page is data-theme='studio' too: landing.css pins its printed
     product previews to their own look where the app's materials differ.
   ========================================================================== */
:where(:root, [data-theme]) {
  /* The light, and what it makes: a line, a glow, a wash on glass. */
  --light: var(--brand);
  --light-hi: color-mix(in srgb, var(--light), #fff 40%);
  --light-line: color-mix(in srgb, var(--light) 40%, transparent);
  --light-glow: color-mix(in srgb, var(--light) 50%, transparent);
  --light-wash: color-mix(in srgb, var(--light) 9%, transparent);
  /* The two ends of a neon rim: the studio's violet and blue, or the salon's two colours. */
  --neon-a: var(--glow-1-soft, var(--light-hi));
  --neon-b: var(--glow-3-soft, var(--light));
  --cta-glow: var(--brand-glow);
  /* Mirror bulbs. */
  --bulb: #ffe2b0; --bulb-core: #fff6e3; --bulb-glow: rgb(255 205 140 / .5); --bulb-off: rgb(255 226 176 / .14);
  /* The pole keeps the classic red, white and blue on every palette, as light. */
  --pole-red: #ff4058; --pole-white: #f6f1e7; --pole-blue: #3f7bff;
  /* Glass: lit from above at its rim, a faint sheen, a lit top edge, a mirror's streaks. */
  --rim-hi: rgb(255 255 255 / .16); --rim-lo: rgb(255 255 255 / .045);
  --rim: linear-gradient(180deg, var(--rim-hi), var(--rim-lo) 38%, var(--rim-lo) 80%, rgb(255 255 255 / .07));
  --pane-sheen: linear-gradient(165deg, rgb(255 255 255 / .045), transparent 42%);
  --pane-edge: linear-gradient(90deg, transparent 8%, color-mix(in srgb, var(--light) 30%, transparent) 50%, transparent 92%) top / 100% 1px no-repeat;
  --mirror-rim: linear-gradient(135deg, var(--neon-a), color-mix(in srgb, var(--neon-a) 38%, transparent) 22%, color-mix(in srgb, var(--neon-b) 10%, transparent) 52%, color-mix(in srgb, var(--neon-b) 40%, transparent) 80%, var(--neon-b));
  --glass-streak: linear-gradient(118deg, transparent 18%, rgb(255 255 255 / .07) 20.5%, rgb(255 255 255 / .02) 23%, transparent 24.5%, transparent 27%, rgb(255 255 255 / .045) 28.5%, transparent 31%);
  --depth-1: inset 0 1px 0 var(--rim-hi), 0 10px 26px -18px rgb(0 0 0 / .85);
  --depth-2: inset 0 1px 0 rgb(255 255 255 / .07), 0 22px 50px -26px rgb(0 0 0 / .95);
  --depth-3: 0 32px 70px -28px rgb(0 0 0 / .95);
  /* A glyph drawn in light glows in its own colour. */
  --glyph-glow: drop-shadow(0 0 6px color-mix(in srgb, currentColor 60%, transparent));
  /* Metal, only inside the barbershop art: the pole's caps, the shears, the coin. */
  --brass: linear-gradient(90deg, #5d3d14, #f2d08a 40%, #a87332 70%, #4a300f);
  --brass-ball: radial-gradient(circle at 35% 30%, #fff3cf, #d8a956 45%, #6d4a17);
  --brass-rim: conic-gradient(from -30deg, #6f4c1c, #e9c47a 7%, #fff0c2 10%, #c79446 15%, #7a5420 26%, #b5823a 36%, #f2d08a 44%, #a87332 52%, #5d3d14 62%, #a7763a 72%, #f6dc9c 80%, #b4843d 88%, #6f4c1c);
  --steel: linear-gradient(180deg, #f4f6f8, #c3cad2 35%, #8d97a2 75%, #e9edf1);
  /* Numerals: time and money read like an instrument, thin and tabular. */
  --w-display: 200; --w-figure: 300;
  --fs-fig-xl: clamp(44px, 12vw, 60px); --fs-fig-l: 34px; --fs-fig-m: 24px;
  /* Motion: a crisp press, a soft release, steps, one sweep. */
  --t-press: 90ms; --t-release: 320ms; --t-quick: 180ms; --t-step: 460ms; --t-sweep: 1100ms;
  --ease-press: cubic-bezier(.3, 0, .6, 1);
  /* A sweep of light: gathers, crosses at an even pace, settles. */
  --ease-sweep: cubic-bezier(.45, .05, .3, 1);
  --spring-soft: cubic-bezier(.22, 1.18, .36, 1);
}
/* A real spring where the engine can draw one (about 3.5% over, then still). */
@supports (transition-timing-function: linear(0, 1)) {
  :where(:root, [data-theme]) { --spring-soft: linear(0, .2 6%, .55 14%, .83 23%, .98 32%, 1.035 41%, 1.03 50%, 1.01 62%, 1 78%, 1); }
}

/* The owner's studio: deep indigo night, violet-to-blue light. Its colours are the
   studio's own; the salon's colours live in its app (previews, icon). */
[data-theme='studio'] {
  color-scheme: dark;
  /* Three lights the studio is lit by. They become the salon's own colours when the
     owner chooses "my salon's colours" for their dashboard (see below). */
  --glow-1: #a855f7; --glow-2: #6366f1; --glow-3: #3b82f6;
  --glow-1-soft: #c4b5fd; --glow-3-soft: #93c5fd;
  --violet: #a78bfa; --blue: #60a5fa;
  --brand: #8b7cff; --on-brand: #fff;
  --grad: linear-gradient(135deg, var(--glow-1) 0%, var(--glow-2) 52%, var(--glow-3) 100%);
  --grad-soft: linear-gradient(135deg, color-mix(in srgb, var(--glow-1) 24%, transparent), color-mix(in srgb, var(--glow-3) 18%, transparent));
  --bg: #0a0918; --bg-2: #0f0d22;
  --surface: #15122c; --surface-2: #1c1839; --surface-3: #262149;
  --line: rgb(167 139 250 / .1); --line-2: rgb(167 139 250 / .18);
  --text: #f4f2ff; --text-2: rgb(228 224 255 / .66); --text-3: rgb(228 224 255 / .56);
  --danger: #ff6b8b; --ok: #34d399; --warn: #fbbf24; --info: #93c5fd;
  --glass: rgb(21 18 44 / .72);
  --shadow: 0 1px 0 rgb(255 255 255 / .04) inset, 0 14px 34px -18px rgb(3 0 20 / .9);
  --shadow-lg: 0 30px 60px -24px rgb(3 0 20 / .95);
  /* Its light: a violet neon (the rims run violet to blue, --glow-1-soft to --glow-3-soft). */
  --light: #c4b5fd;
}
/* The salon's page by day: light, the accent inked dark enough to read on white. */
[data-theme='public'][data-page='day'] {
  color-scheme: light;
  --brand: var(--accent-ink); --on-brand: var(--on-accent-ink);
  --grad: linear-gradient(135deg, color-mix(in srgb, var(--accent-ink), #fff 16%), var(--accent-ink) 50%, color-mix(in srgb, var(--accent-ink), #000 14%));
  --grad-soft: color-mix(in srgb, var(--accent-ink) 12%, transparent);
  --bg: var(--day); --bg-2: #fff;
  --surface: #fff; --surface-2: color-mix(in srgb, var(--day), #000 3%); --surface-3: color-mix(in srgb, var(--day), #000 7%);
  --line: rgb(20 18 16 / .08); --line-2: rgb(20 18 16 / .14);
  --text: #1b1a19; --text-2: #67635d; --text-3: #9a958d;
  --danger: #c62828; --ok: #1e7d3a; --warn: #b45309; --info: #1d4ed8;
  --glass: rgb(255 255 255 / .8);
  --shadow: 0 1px 2px rgb(0 0 0 / .04), 0 10px 28px -14px rgb(0 0 0 / .16);
  --shadow-lg: 0 24px 50px -20px rgb(0 0 0 / .3);
  /* By day light does not glow: the accent's ink draws the lines, white paper the rims. */
  --light: var(--accent-ink); --light-hi: var(--accent-ink); --light-glow: transparent;
  --neon-a: color-mix(in srgb, var(--accent-ink) 55%, #fff); --neon-b: var(--accent-ink);
  --rim-hi: rgb(255 255 255 / .95); --rim-lo: rgb(20 18 16 / .07); --pane-sheen: none; --pane-edge: none; --glyph-glow: none;
  --depth-1: 0 1px 2px rgb(0 0 0 / .04), 0 10px 28px -14px rgb(0 0 0 / .16);
  --depth-2: 0 24px 50px -20px rgb(0 0 0 / .3);
  --mirror-rim: linear-gradient(180deg, color-mix(in srgb, var(--accent-ink) 45%, #fff), rgb(20 18 16 / .1));
}
/* The owner's dashboard in the salon's own colours: its night as the room, its
   accent as the main light and its main colour as the second. Buttons take the
   accent's own metallic shades, so their text always reads. */
[data-theme='studio'][data-studio='brand']:not([data-platform]) {
  --glow-1: var(--accent-lift); --glow-3: var(--primary-lift);
  --glow-2: color-mix(in srgb, var(--accent-lift), var(--primary-lift));
  --glow-1-soft: color-mix(in srgb, var(--accent-lift), #fff 45%); --glow-3-soft: color-mix(in srgb, var(--primary-lift), #fff 45%);
  --violet: color-mix(in srgb, var(--accent-lift), #fff 15%); --blue: color-mix(in srgb, var(--primary-lift), #fff 15%);
  --brand: var(--accent-lift); --on-brand: var(--on-accent-lift);
  --grad: linear-gradient(135deg, color-mix(in srgb, var(--accent-lift), #fff 24%), var(--accent-lift) 48%, color-mix(in srgb, var(--accent-lift), #000 16%));
  --bg: var(--night); --bg-2: color-mix(in srgb, var(--night), #fff 4%);
  --surface: color-mix(in srgb, var(--night), #fff 7%); --surface-2: color-mix(in srgb, var(--night), #fff 10%); --surface-3: color-mix(in srgb, var(--night), #fff 15%);
  --line: rgb(255 255 255 / .08); --line-2: rgb(255 255 255 / .15);
  --text: #f7f4ef; --text-2: rgb(247 244 239 / .68); --text-3: rgb(247 244 239 / .56);
  --glass: color-mix(in srgb, var(--night) 72%, transparent);
  /* Lit by the salon's accent; its rims run accent to main colour. */
  --light: var(--accent-lift); --bulb: color-mix(in srgb, var(--accent-lift), #fff 35%);
}
/* The salon's page: its own night. The base is the salon's main colour deep in
   near-black (--night); the light is its accent (--accent-lift, lightened only if it
   would not read). Both come from the server with the first paint. */
[data-theme='public'] {
  color-scheme: dark;
  --brand: var(--accent-lift); --on-brand: var(--on-accent-lift);
  --grad: linear-gradient(135deg, color-mix(in srgb, var(--accent-lift), #fff 24%), var(--accent-lift) 48%, color-mix(in srgb, var(--accent-lift), #000 16%));
  --grad-soft: color-mix(in srgb, var(--accent-lift) 16%, transparent);
  --bg: var(--night); --bg-2: color-mix(in srgb, var(--night), #fff 5%);
  --surface: color-mix(in srgb, var(--night), #fff 7%); --surface-2: color-mix(in srgb, var(--night), #fff 10%); --surface-3: color-mix(in srgb, var(--night), #fff 15%);
  --line: rgb(255 255 255 / .08); --line-2: rgb(255 255 255 / .15);
  --text: #f7f4ef; --text-2: rgb(247 244 239 / .7); --text-3: rgb(247 244 239 / .46);
  --danger: #ff7a7a; --ok: #4ade80; --warn: #fbbf24; --info: #93c5fd;
  --glass: color-mix(in srgb, var(--night) 70%, transparent);
  --shadow: 0 1px 0 rgb(255 255 255 / .05) inset, 0 16px 36px -20px rgb(0 0 0 / .85);
  --shadow-lg: 0 30px 60px -24px rgb(0 0 0 / .95);
  /* Lit by its own accent (--light is --brand here); the bulbs take a breath of it. */
  --bulb: color-mix(in srgb, var(--accent-lift), #fff 35%);
}
:root {
  --brand-soft: color-mix(in srgb, var(--brand) 15%, transparent);
  --brand-line: color-mix(in srgb, var(--brand) 42%, transparent);
  --brand-glow: color-mix(in srgb, var(--brand) 55%, transparent);
}

/* ---------------------------------------------------------------- base */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
body {
  margin: 0; min-height: 100dvh; background: var(--bg); color: var(--text);
  font: 400 16px/1.6 var(--font);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent; text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, p, figure { margin: 0; }
h1, h2, h3 { font-weight: 700; line-height: 1.25; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-appearance: none; appearance: none; }
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }
::selection { background: var(--brand-soft); }
/* The focus ring is the screen's light; on capsules it stands a little further off. */
:focus-visible { outline: 2px solid var(--light); outline-offset: 2px; }
.btn:focus-visible { outline-offset: 3px; }
:lang(en) h1, :lang(en) .display { letter-spacing: -.02em; }

.muted { color: var(--text-2); }
.faint { color: var(--text-3); }
.small { font-size: 13px; }
.ltr { direction: ltr; unicode-bidi: isolate; }
.num { font-variant-numeric: tabular-nums; }
.row { display: flex; align-items: center; gap: 12px; }
.row.between { justify-content: space-between; }
.row.wrap { flex-wrap: wrap; }
.grow { flex: 1; min-width: 0; }
.stack > * + * { margin-top: 12px; }
.stack-sm > * + * { margin-top: 8px; }
.stack-lg > * + * { margin-top: 24px; }
.center { text-align: center; }
.truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
[dir='rtl'] .flip-rtl, [dir='ltr'] .flip-ltr { transform: scaleX(-1); }

/* entrance: add .rise and set --i for a stagger */
.rise { animation: rise .6s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 50ms); }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes fade { from { opacity: 0; } }
@keyframes pop { from { opacity: 0; transform: scale(.92); } }
@keyframes spin { to { transform: rotate(360deg); } }

.boot { min-height: 100dvh; display: grid; place-items: center; }
/* The shell's "could not load" screen: an alert mark, the reason, a way to try again. */
.boot .fail { padding: 24px 16px; animation: rise .5s var(--ease-out) both; }
.boot .fail p { max-width: 32ch; margin-inline: auto; color: var(--text-2); }
.boot .fail .btn { margin-top: 20px; }
.fail-mark { display: inline-grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); box-shadow: 0 0 0 8px color-mix(in srgb, var(--danger) 6%, transparent); }
.fail-mark .icon { width: 26px; height: 26px; }
.spinner { width: 26px; height: 26px; border-radius: 50%; border: 2.5px solid var(--line-2); border-top-color: var(--brand); animation: spin .8s linear infinite; }

/* Loading: a plain pane with one soft light passing over it, on translate (the compositor
   draws it), never background-position. */
.skel { position: relative; overflow: hidden; border-radius: var(--r); background: var(--surface); }
.skel::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, var(--surface-2), transparent); translate: -100% 0; animation: skel-pass 1.6s linear infinite; }
@keyframes skel-pass { to { translate: 100% 0; } }

/* ---------------------------------------------------------------- icons */
.icon { width: 20px; height: 20px; flex: none; }

/* ---------------------------------------------------------------- buttons */
/* Buttons are capsules. A press goes down fast and crisp; the release comes back on a soft spring. */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 52px; padding: 0 22px; border-radius: 999px; border: 1px solid transparent;
  font-size: 16px; font-weight: 600; white-space: nowrap; cursor: pointer; user-select: none;
  transition: transform var(--t-release) var(--spring-soft), background-color .2s, box-shadow .25s, opacity .2s, border-color .2s;
}
.btn:active { transform: translateY(1px) scale(.975); transition-duration: var(--t-press); transition-timing-function: var(--ease-press); }
.btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn .icon { width: 19px; height: 19px; }
/* The main action keeps its fill and wears the screen's light as a neon rim: a glass edge
   inside, a lit line and its bloom outside. Pressed, the bloom draws in. */
.btn-primary {
  background: var(--grad, var(--brand)); color: var(--on-brand); overflow: hidden; isolation: isolate;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .3), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 22px -6px var(--light-glow), 0 14px 32px -16px var(--cta-glow);
}
.btn-primary:active { box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 12px -6px var(--light-glow), 0 8px 20px -14px var(--cta-glow); }
/* One light sweep across it: on hover with a mouse, and once for .sheen (never on a loop).
   It moves on translate, so the compositor draws it. */
.btn-primary::before { content: ''; position: absolute; inset: 0 -40%; z-index: -1; pointer-events: none; background: linear-gradient(110deg, transparent 35%, rgb(255 255 255 / .38) 50%, transparent 65%); translate: -100% 0; }
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { box-shadow: inset 0 1px 0 rgb(255 255 255 / .3), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 30px -6px var(--light-glow), 0 18px 40px -16px var(--cta-glow); }
  .btn-primary:hover::before { animation: sheen-x 1s var(--ease-sweep); }
}
.btn-primary.sheen::before { animation: sheen-x 1.4s var(--ease-sweep) .6s 1 both; }
@keyframes sheen-x { from { translate: -100% 0; } to { translate: 100% 0; } }
[dir='rtl'] .btn-primary::before { translate: 100% 0; }
[dir='rtl'] .btn-primary:hover::before, [dir='rtl'] .btn-primary.sheen::before { animation-name: sheen-x-rtl; }
@keyframes sheen-x-rtl { from { translate: 100% 0; } to { translate: -100% 0; } }
.btn-accent { background: var(--accent); color: var(--on-accent); }
.btn-secondary { background: var(--surface-2); color: var(--text); border-color: var(--line-2); box-shadow: inset 0 1px 0 var(--rim-lo); }
.btn-secondary:hover { background: var(--surface-3); }
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover { color: var(--text); background: var(--surface-2); }
.btn-danger { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
.btn-sm { height: 40px; padding: 0 15px; font-size: 14px; }
.btn-block { width: 100%; }
/* Working: a barber's pole turns across the button (in place of a spinner). The stripes
   repeat every 16px across the gradient, 18.48px along the button (16 / sin 60deg), so
   one step of that is a seamless loop. */
.btn.busy { color: transparent !important; pointer-events: none; overflow: hidden; }
.btn.busy::after {
  --stripe: color-mix(in srgb, var(--on-brand) 30%, transparent);
  content: ''; position: absolute; inset-block: 0; inset-inline: -40px 0; z-index: 1;
  background: repeating-linear-gradient(120deg, var(--stripe) 0 8px, transparent 8px 16px); animation: pole-x .9s linear infinite;
}
[dir='rtl'] .btn.busy::after { background: repeating-linear-gradient(60deg, var(--stripe) 0 8px, transparent 8px 16px); animation-name: pole-x-rtl; }
.btn-secondary.busy::after, .btn-ghost.busy::after, .btn-danger.busy::after { --stripe: color-mix(in srgb, var(--text) 22%, transparent); }
@keyframes pole-x { to { translate: 18.48px 0; } }
@keyframes pole-x-rtl { to { translate: -18.48px 0; } }

.icon-btn {
  display: inline-grid; place-items: center; flex: none; width: 44px; height: 44px; border-radius: 14px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text); cursor: pointer;
  transition: transform .2s var(--spring), background-color .2s;
}
.icon-btn:hover { background: var(--surface-3); }
.icon-btn:active { transform: scale(.92); }
.icon-btn.plain { background: transparent; border-color: transparent; }
.icon-btn.on { background: var(--brand-soft); border-color: var(--brand-line); color: var(--brand); }
.icon-btn.danger { color: var(--danger); }
.icon-btn.busy > * { opacity: 0; }
.icon-btn.busy::after { content: ''; position: absolute; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--text); border-color: var(--text) transparent; animation: spin .7s linear infinite; }
.icon-btn { position: relative; }

.link-btn { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; padding: 6px 2px; color: var(--brand); font-weight: 500; font-size: 14px; cursor: pointer; }
.link-btn .icon { width: 17px; height: 17px; }

/* ---------------------------------------------------------------- fields (floating labels) */
.f { position: relative; display: block; }
.f + .f, .f + .f-row, .f-row + .f, .f-row + .f-row { margin-top: 12px; }
.f-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.f-row > .f { margin: 0; }
.f > input, .f > textarea, .f > select {
  display: block; width: 100%; height: 60px; padding: 26px 16px 8px; font-size: 16px;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--line); border-radius: var(--r);
  outline: none; transition: border-color .2s, box-shadow .2s, background-color .2s;
}
.f > textarea { height: auto; min-height: 104px; max-height: 50dvh; padding-top: 30px; resize: none; field-sizing: content; line-height: 1.55; }
.f > select { appearance: none; cursor: pointer; padding-inline-end: 40px; }
.f > .label {
  position: absolute; inset-inline-start: 17px; top: 19px; max-width: calc(100% - 34px); color: var(--text-3); font-size: 16px; pointer-events: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: top .2s var(--ease-out), font-size .2s var(--ease-out), color .2s;
}
.f > input:focus ~ .label, .f > input:not(:placeholder-shown) ~ .label,
.f > textarea:focus ~ .label, .f > textarea:not(:placeholder-shown) ~ .label,
.f > select ~ .label, .f.fixed > .label { top: 9px; font-size: 12px; color: var(--text-2); }
.f > input:focus, .f > textarea:focus, .f > select:focus { border-color: var(--brand-line); box-shadow: 0 0 0 4px var(--brand-soft); background: var(--surface-3); }
.f > input::placeholder, .f > textarea::placeholder { color: transparent; }
.f > .suffix { position: absolute; inset-inline-end: 16px; top: 27px; color: var(--text-3); font-size: 15px; pointer-events: none; }
.f > .chev { position: absolute; inset-inline-end: 16px; top: 22px; width: 16px; height: 16px; color: var(--text-3); pointer-events: none; }
.f > .hint { display: block; margin-top: 6px; font-size: 12.5px; color: var(--text-3); }
.f.invalid > input, .f.invalid > textarea, .f.invalid > select { border-color: var(--danger); box-shadow: 0 0 0 4px color-mix(in srgb, var(--danger) 15%, transparent); }
.f .optional { color: var(--text-3); font-size: .85em; }
.f > input[type='tel'], .f > input.num, .f > input[dir='ltr'] { direction: ltr; text-align: end; }
[dir='ltr'] .f > input[type='tel'], [dir='ltr'] .f > input.num, [dir='ltr'] .f > input[dir='ltr'] { text-align: start; }
/* Free text in either script (names, notes, an address) takes the direction of what is
   typed, so "John!" or "صالون!" keeps its punctuation; an empty field keeps the page's. */
.f > input[type='text']:not([dir]):not(.num), .f > textarea:not([dir]) { unicode-bidi: plaintext; }
.form-error { color: var(--danger); font-size: 14px; margin-top: 12px; }

/* ---------------------------------------------------------------- switch, chips, segmented */
.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; flex: none; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch .track { width: 50px; height: 30px; border-radius: 999px; background: var(--surface-3); border: 1px solid var(--line-2); position: relative; transition: background-color .25s, border-color .25s; }
.switch .track::after {
  content: ''; position: absolute; top: 2px; inset-inline-start: 2px; width: 24px; height: 24px; border-radius: 50%;
  background: #fff; box-shadow: 0 2px 6px rgb(0 0 0 / .35); transition: inset-inline-start .3s var(--spring);
}
.switch input:checked + .track { background: var(--grad, var(--brand)); border-color: transparent; box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), 0 0 0 1px var(--light-line), 0 0 16px -4px var(--light-glow); }
.switch input:checked + .track::after { inset-inline-start: 22px; }
.switch input:focus-visible + .track { outline: 2px solid var(--light); outline-offset: 2px; }
.switch-row { display: flex; align-items: center; gap: 14px; min-height: 56px; }
.switch-row .grow > div:first-child { font-weight: 500; }
.switch-row .grow > div + div { font-size: 13px; color: var(--text-2); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { position: relative; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.chip > span {
  display: inline-flex; align-items: center; gap: 8px; height: 42px; padding: 0 14px 0 14px; border-radius: 14px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); font-size: 14.5px; font-weight: 500;
  transition: background-color .2s, border-color .2s, color .2s, transform .2s var(--spring);
}
.chip > span .avatar { width: 28px; height: 28px; margin-inline-start: -8px; font-size: 12px; }
.chip > span .svc-ic { width: 17px; height: 17px; color: var(--violet, var(--brand)); }
.chip:active > span { transform: scale(.96); }
.chip input:checked + span { background: var(--brand-soft); border-color: var(--brand-line); color: var(--text); }
.chip input:focus-visible + span { outline: 2px solid var(--light); outline-offset: 2px; }
.chip-btn { display: inline-flex; align-items: center; gap: 8px; height: 42px; padding: 0 16px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); font-weight: 500; font-size: 14.5px; cursor: pointer; white-space: nowrap; transition: background-color .2s, color .2s, border-color .2s, transform .2s var(--spring); }
.chip-btn:active { transform: scale(.95); }
.chip-btn.on { background: var(--brand-soft); border-color: var(--brand-line); color: var(--text); }
/* On its way (the guide's "add me"): a second tap waits. */
.chip-btn.busy { opacity: .6; pointer-events: none; }
/* A strip that runs to the edge of its container (--bleed: the container's padding)
   and starts where the content starts. */
.scroller { --bleed: 16px; display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; margin-inline: calc(var(--bleed) * -1); padding: 2px var(--bleed) 6px; scroll-padding-inline: var(--bleed); scroll-snap-type: x proximity; }
.scroller::-webkit-scrollbar { display: none; }
.scroller > * { flex: none; scroll-snap-align: start; }
.sheet-body .scroller { --bleed: 20px; }
.card .scroller { --bleed: 18px; }
/* In the studio a strip fades out at whichever edge has more to scroll to. */
@property --fade-s { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --fade-e { syntax: '<length>'; inherits: false; initial-value: 0px; }
@supports (animation-timeline: scroll()) {
  :where([data-theme='studio']) .scroller {
    --fade-dir: 90deg;
    -webkit-mask-image: linear-gradient(var(--fade-dir), transparent, #000 var(--fade-s), #000 calc(100% - var(--fade-e)), transparent);
    mask-image: linear-gradient(var(--fade-dir), transparent, #000 var(--fade-s), #000 calc(100% - var(--fade-e)), transparent);
    animation: strip-edges linear both; animation-timeline: scroll(self inline);
  }
  :where([dir='rtl'][data-theme='studio']) .scroller { --fade-dir: 270deg; }
}
@keyframes strip-edges { 0% { --fade-s: 0px; --fade-e: 36px; } 6% { --fade-s: 36px; } 94% { --fade-e: 36px; } 100% { --fade-s: 36px; --fade-e: 0px; } }

.segmented { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; padding: 4px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 16px; }
.segmented label { position: relative; cursor: pointer; }
.segmented input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.segmented span { display: grid; place-items: center; height: 42px; border-radius: 12px; color: var(--text-2); font-size: 14.5px; font-weight: 500; transition: background-color .25s, color .25s, box-shadow .25s; }
.segmented input:checked + span { background: var(--surface-3); color: var(--text); box-shadow: 0 4px 12px -4px rgb(0 0 0 / .5); }
.segmented input:focus-visible + span { outline: 2px solid var(--light); outline-offset: -2px; }

/* ---------------------------------------------------------------- surfaces */
/* A pane: smoked glass with a lit top edge, a faint sheen and a rim from above. A variant
   that paints its own background or shadow keeps it (its border still gives the edge). */
.card { background: var(--pane-edge), var(--pane-sheen), var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 18px; box-shadow: var(--depth-1); }
.card.flush { padding: 0; overflow: hidden; }
/* The lit card: a still neon rim (the light's two ends at opposite corners) over its two glows. */
.card.glow {
  position: relative; border: 1.5px solid transparent; box-shadow: var(--depth-2), 0 24px 70px -30px var(--light-glow);
  background: radial-gradient(110% 90% at 100% 0%, color-mix(in srgb, var(--glow-1, var(--light)) 22%, transparent), transparent 55%) padding-box, radial-gradient(90% 80% at 0% 100%, color-mix(in srgb, var(--glow-3, var(--light)) 16%, transparent), transparent 60%) padding-box, linear-gradient(var(--surface), var(--surface)) padding-box, var(--mirror-rim) border-box;
}
@keyframes orbit { to { --angle: 360deg; } }
/* The mirror: at most one per screen, for what the screen is about. The neon rim, a wash of
   light from above and the glass's streaks; the first time it is seen in a session
   (sweepOnce) a band of light crosses it once and the streaks settle into place. */
.mirror {
  position: relative; isolation: isolate; overflow: hidden; border: 1.5px solid transparent;
  background: radial-gradient(120% 70% at 50% -10%, var(--light-wash), transparent 60%) padding-box, linear-gradient(var(--surface), var(--surface)) padding-box, var(--mirror-rim, var(--rim)) border-box;
  box-shadow: var(--depth-2), 0 18px 48px -26px var(--light-glow);
}
.mirror::after { content: ''; position: absolute; inset: -20% -60%; z-index: -1; pointer-events: none; background: var(--glass-streak); }
.mirror.sweep::after { animation: mirror-sweep var(--t-sweep) var(--ease-out) .25s both; }
.mirror.sweep::before {
  content: ''; position: absolute; inset: 0 -50%; z-index: -1; pointer-events: none; translate: -100% 0;
  background: linear-gradient(105deg, transparent 40%, color-mix(in srgb, var(--light) 16%, transparent) 46.5%, rgb(255 255 255 / .16) 50%, color-mix(in srgb, var(--light) 16%, transparent) 53.5%, transparent 60%);
  animation: sheen-x var(--t-sweep) var(--ease-sweep) .25s both;
}
[dir='rtl'] .mirror.sweep::after { animation-name: mirror-sweep-rtl; }
[dir='rtl'] .mirror.sweep::before { translate: 100% 0; animation-name: sheen-x-rtl; }
@keyframes mirror-sweep { from { translate: -45% 0; } }
@keyframes mirror-sweep-rtl { from { translate: 45% 0; } }
.card-title { font-size: 17px; font-weight: 600; }
.card-sub { font-size: 13.5px; color: var(--text-2); margin-top: 2px; }

.section { margin-top: 28px; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 4px 12px; }
.section-head .link-btn { padding-block: 0; }
.section-head h2 { font-size: 17px; font-weight: 600; }
.section-head p { font-size: 13px; color: var(--text-2); }
.eyebrow { font-size: 12.5px; font-weight: 500; color: var(--text-3); }

.list { list-style: none; margin: 0; padding: 0; }
.list > li + li { border-top: 1px solid var(--line); }

.pill { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 11px; border-radius: 999px; font-size: 12.5px; font-weight: 500; background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line); white-space: nowrap; }
.pill .icon { width: 14px; height: 14px; }
.pill.brand { background: var(--brand-soft); color: var(--text); border-color: var(--brand-line); }
.pill.ok { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); border-color: transparent; }
.pill.off { color: var(--text-3); }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); flex: none; }
.dot.ok { background: var(--ok); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 20%, transparent); }
.count { display: inline-grid; place-items: center; min-width: 28px; height: 28px; padding: 0 8px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); font-size: 13px; font-weight: 600; color: var(--text-2); vertical-align: middle; }

/* An icon's tile is a lit bezel: dark glass, a breath of the light from its top corner, the
   glyph drawn in light with its own glow. Tiles that take a status colour keep it. */
.tile {
  display: grid; place-items: center; flex: none; width: 46px; height: 46px; border-radius: 14px;
  background: radial-gradient(120% 120% at 30% 0, var(--light-wash), transparent 60%), var(--surface-2);
  color: var(--light); box-shadow: inset 0 1px 0 var(--rim-hi), inset 0 0 0 1px var(--line);
}
.tile .icon { width: 22px; height: 22px; filter: var(--glyph-glow); }

.avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none; display: grid; place-items: center; background: var(--surface-3); color: var(--text-2); font-weight: 600; font-size: 15px; overflow: hidden; }
.avatar-stack { display: flex; align-items: center; }
.avatar-stack .avatar { width: 26px; height: 26px; font-size: 11px; border: 2px solid var(--surface); }
.avatar-stack .avatar + .avatar { margin-inline-start: -9px; }

.portrait { position: relative; aspect-ratio: 4 / 5; border-radius: var(--r-lg); overflow: hidden; background: var(--surface-2); }
.portrait > img { width: 100%; height: 100%; object-fit: cover; }
.portrait .placeholder { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-3); }
.portrait .placeholder .icon { width: 38px; height: 38px; opacity: .6; }

.empty { text-align: center; padding: 32px 20px; color: var(--text-2); }
.empty .tile { margin: 0 auto 14px; width: 60px; height: 60px; border-radius: 18px; }

/* progress ring */
.ring { position: relative; width: var(--size, 92px); height: var(--size, 92px); flex: none; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 8; }
.ring .track { stroke: var(--line-2); }
.ring .value { stroke-linecap: round; transition: stroke-dashoffset 1.4s var(--ease-out); filter: drop-shadow(0 0 7px var(--brand-glow)); }
.ring .label { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; line-height: 1.1; }
.ring .label b { display: block; font-size: 24px; font-weight: 700; }
.ring .label span { font-size: 11px; color: var(--text-2); }

/* ---------------------------------------------------------------- Neon Barber primitives
   Shared by the guided setup, the guided booking and the booking's timeline. */

/* A figure: money or time as the display type. Only the digits are isolated left to right,
   so the unit keeps the reading side: "12 د.أ." in Arabic, "12 JD" in English. */
.fig { display: inline-flex; align-items: baseline; gap: .22em; font-variant-numeric: tabular-nums lining-nums; line-height: 1.05; color: var(--text); }
.fig > b { font-weight: inherit; direction: ltr; unicode-bidi: isolate; }
.fig .unit { font-size: max(13px, .3em); font-weight: 500; color: var(--text-2); }
.fig.xl { font-size: var(--fs-fig-xl); font-weight: var(--w-display); }
.fig.l { font-size: var(--fs-fig-l); font-weight: var(--w-display); }
.fig.m { font-size: var(--fs-fig-m); font-weight: var(--w-figure); }

/* A folio, as the landing numbers its sections: a hairline, the number in the light, a word. */
.folio { display: flex; align-items: center; gap: 10px; font-size: 12.5px; font-weight: 500; line-height: 1.4; color: var(--text-3); }
.folio::before { content: ''; flex: none; width: 24px; height: 1px; background: currentColor; opacity: .6; }
.folio-n { color: var(--light); font-variant-numeric: tabular-nums; }
:lang(en) .folio { text-transform: uppercase; letter-spacing: .14em; }

/* A ring of mirror bulbs (bulbRing() in dom.js): n bulbs at radius --rd, each lit or off.
   Zero specificity, so every ring's own rules (.mini-lights, .p-lights, .mr-bulbs) win. */
:where(.bulbs) { position: absolute; inset: 0; pointer-events: none; }
:where(.bulbs) i {
  position: absolute; left: 50%; top: 50%; width: var(--bs, 5px); height: var(--bs, 5px); margin: calc(var(--bs, 5px) / -2); border-radius: 50%;
  background: var(--bulb-off); transform: rotate(calc(var(--i) * 360deg / var(--n, 18))) translateY(calc(var(--rd, 40px) * -1));
  transition: background-color .3s, box-shadow .3s;
}
:where(.bulbs) i:where(.on) { background: var(--bulb-core); box-shadow: 0 0 8px 1px var(--bulb-glow); }
/* Switching on like a real bulb: two dips before it holds (never a strobe). */
:where(.bulbs) i:where(.flash) { animation: bulb-on .7s linear both; }
@keyframes bulb-on { 0% { opacity: .2; } 18% { opacity: 1; } 30% { opacity: .35; } 52% { opacity: 1; } 64% { opacity: .6; } 100% { opacity: 1; } }

/* The barber's pole as light: red, white and blue stripes on every palette (the halo is
   the screen's light). The stripes repeat every 28px across the gradient, 32.33px along it
   (28 / sin 60deg): a seamless turn in full motion, still otherwise. */
.pole-stripes {
  position: absolute; inset-block: 0; inset-inline: -40px 0; pointer-events: none;
  background: repeating-linear-gradient(120deg, var(--pole-red) 0 7px, var(--pole-white) 7px 14px, var(--pole-blue) 14px 21px, var(--pole-white) 21px 28px);
}
[dir='rtl'] .pole-stripes { background: repeating-linear-gradient(60deg, var(--pole-red) 0 7px, var(--pole-white) 7px 14px, var(--pole-blue) 14px 21px, var(--pole-white) 21px 28px); }
:root[data-motion='full'] .pole-stripes { animation: pole-stripe 2.4s linear infinite; }
:root[data-motion='full'][dir='rtl'] .pole-stripes { animation-name: pole-stripe-rtl; }
@keyframes pole-stripe { to { translate: 32.33px 0; } }
@keyframes pole-stripe-rtl { to { translate: -32.33px 0; } }

/* Progress as a lit pole (poleBar() in dom.js): brass caps, a glass tube, the striped
   light sliding in from the start (a transform, not a width), a spark where it grew. */
.pole-bar { position: relative; display: flex; align-items: center; height: 12px; --p: 0; }
.pole-cap { flex: none; width: 6px; height: 12px; border-radius: 3px; background: var(--brass); }
.pole-track { position: relative; flex: 1; height: 8px; overflow: hidden; overflow: clip; border-radius: 99px; background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line), inset 0 2px 4px rgb(0 0 0 / .35); }
.pole-fill { position: absolute; inset: 0; overflow: hidden; overflow: clip; border-radius: inherit; translate: calc((var(--p) - 1) * 100%) 0; transition: translate .6s var(--ease-out); box-shadow: 0 0 12px -2px var(--light-glow); }
[dir='rtl'] .pole-fill { translate: calc((1 - var(--p)) * 100%) 0; }
/* The tube's roundness over the stripes. */
.pole-fill::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgb(255 255 255 / .35), transparent 45%, rgb(0 0 0 / .3)); }
.pole-spark { position: absolute; top: 50%; inset-inline-start: calc(6px + var(--p) * (100% - 12px)); width: 10px; height: 10px; margin: -5px; border-radius: 50%; background: var(--bulb-core); box-shadow: 0 0 10px 2px var(--light-glow), 0 0 4px var(--bulb-glow); opacity: 0; pointer-events: none; }
.pole-bar.spark .pole-spark { animation: pole-spark .6s ease-out; }
@keyframes pole-spark { 0%, 100% { opacity: 0; scale: .6; } 35% { opacity: 1; scale: 1; } }

/* A step in a sequence (the guide's rail, the booking's rail, the timeline): a node that is
   done (lit), now (ringed, one ping) or failed. */
.step-node {
  display: grid; place-items: center; flex: none; width: var(--sn, 28px); height: var(--sn, 28px); border-radius: 50%;
  background: var(--surface-2); color: var(--text-3); box-shadow: inset 0 0 0 1.5px var(--line-2);
  font-size: 12px; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums;
}
.step-node .icon { width: 55%; height: 55%; stroke-width: 2.4; }
.step-node[data-state='done'] { background: var(--light); color: var(--bg); box-shadow: 0 0 12px -2px var(--light-glow); }
.step-node[data-state='now'] { position: relative; background: color-mix(in srgb, var(--light) 18%, var(--surface-2)); color: var(--text); box-shadow: inset 0 0 0 1.5px var(--light), 0 0 0 4px var(--light-wash); }
:root[data-motion='full'] .step-node[data-state='now']::after { content: ''; position: absolute; inset: -1px; border-radius: 50%; border: 2px solid var(--light); animation: ping 1.8s var(--ease-out) 1 both; pointer-events: none; }
.step-node[data-state='fail'] { background: color-mix(in srgb, var(--danger) 16%, var(--surface-2)); color: var(--danger); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--danger) 60%, transparent); }

/* ---------------------------------------------------------------- the barbershop kit
   barber-art.js: the barber's pole as a lit sign, the landing's steel shears and their
   clippings, the ribbon cut. Brass and steel live only here (the pole's caps, the coin,
   the shears); everything else is the screen's light. Only transform and opacity move. */

/* The pole in its round glass seal (it fills a positioned box). The stripes are the classic
   red, white and blue as light on every palette, so it always reads as a barber's; the halo
   and the rim are the screen's light. --lit is how much it is on (0, .45, 1): the halo, the
   rim, the light in the tube and the dark veil over it all follow it. The stripes repeat
   every 24px across the gradient, 48px down the tube (2 * --pp). */
.bk-pole {
  --pp: 24px; --x-dir: 1;
  position: absolute; inset: 0; display: grid; place-items: center; border-radius: 50%;
  background: radial-gradient(85% 85% at 50% 26%, color-mix(in srgb, var(--light) 14%, var(--surface-2)), var(--surface) 60%, color-mix(in srgb, var(--bg), #000 30%));
  box-shadow: inset 0 1px 0 var(--rim-hi), inset 0 0 0 1px var(--line-2), inset 0 -12px 26px -14px rgb(0 0 0 / .8), 0 20px 44px -24px rgb(0 0 0 / .9);
}
[dir='ltr'] .bk-pole { --x-dir: -1; }
.ps-halo {
  position: absolute; inset: -26%; border-radius: 50%; pointer-events: none; opacity: calc(var(--lit) * .8);
  background: radial-gradient(15% 33% at 50% 50%, rgb(255 246 238 / .5), transparent), radial-gradient(closest-side, color-mix(in srgb, var(--light) 44%, transparent), color-mix(in srgb, var(--neon-a) 14%, transparent) 60%, transparent);
}
/* A neon ring at the glass's edge. */
.ps-rim {
  position: absolute; inset: 0; border-radius: 50%; pointer-events: none; opacity: calc(.28 + var(--lit) * .72);
  background: conic-gradient(from 200deg, var(--neon-a), color-mix(in srgb, var(--neon-a) 16%, transparent) 20%, var(--neon-b) 48%, color-mix(in srgb, var(--neon-b) 16%, transparent) 72%, var(--neon-a));
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px)); mask: radial-gradient(closest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px));
}
.ps-glint { position: absolute; inset: 0; border-radius: 50%; overflow: hidden; overflow: clip; pointer-events: none; }
.ps-glint::before {
  content: ''; position: absolute; inset: -10% -70%; opacity: 0;
  background: linear-gradient(104deg, transparent 45%, color-mix(in srgb, var(--light) 55%, transparent) 49.4%, rgb(255 255 255 / .38) 50%, color-mix(in srgb, var(--light) 55%, transparent) 50.6%, transparent 55%);
}
/* Centred with its finial (8px over the top), at any size of seal, the small tile's too. */
.ps-pole { position: absolute; left: 50%; top: 50%; display: flex; flex-direction: column; width: 26px; height: 78px; margin: -35px 0 0 -13px; }
.ps-cap { position: relative; flex: none; height: 11px; margin-inline: -5px; border-radius: 40% 40% 3px 3px; background: var(--brass); box-shadow: 0 2px 3px -1px rgb(0 0 0 / .5); }
.ps-cap:first-child::before { content: ''; position: absolute; left: 50%; top: -8px; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%; background: var(--brass-ball); }
.ps-cap:last-child { border-radius: 3px 3px 40% 40%; box-shadow: 0 -2px 3px -1px rgb(0 0 0 / .4); }
.ps-tube { position: relative; flex: 1; overflow: hidden; overflow: clip; background: var(--pole-white); box-shadow: inset 0 0 0 1px rgb(0 0 0 / .16); }
.ps-stripes {
  position: absolute; inset: calc(var(--pp) * -24) 0 0;
  background: repeating-linear-gradient(60deg, var(--pole-red) 0 6px, var(--pole-white) 6px 12px, var(--pole-blue) 12px 18px, var(--pole-white) 18px 24px);
}
/* Lit from inside: a white core down the tube and the screen's light rising from its foot. */
.ps-light {
  position: absolute; inset: 0; transform-origin: 50% 100%; opacity: var(--lit);
  background: linear-gradient(90deg, transparent 18%, rgb(255 255 255 / .42) 50%, transparent 82%), linear-gradient(to top, color-mix(in srgb, var(--light) 40%, transparent), transparent 75%);
}
.ps-veil { position: absolute; inset: 0; background: rgb(12 10 20 / .66); opacity: calc(1 - var(--lit)); }
/* The glass: dark at the edges, a highlight down one side. */
.ps-tube::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgb(0 0 0 / .45), transparent 32%, rgb(255 255 255 / .55) 44%, transparent 58%, rgb(0 0 0 / .5)); }
/* A brass coin at the pole's foot: a check once confirmed, a lock while the time is held. */
.ps-coin {
  position: absolute; inset-inline-end: 14px; bottom: 12px; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
  color: #3a2506; background: var(--brass-ball);
  box-shadow: 0 4px 10px -3px rgb(0 0 0 / .65), inset 0 0 0 1px rgb(255 240 200 / .5), 0 0 0 2px color-mix(in srgb, var(--bg) 70%, transparent);
}
.ps-coin .icon { width: 16px; height: 16px; stroke-width: 2.8; }
/* The barber's chair a booking holds (barberChair), in the same seal: as lit as --lit, the
   coin saying where the booking stands. It faces where reading starts, so the coin sits by
   its footrest in Arabic and in English; sized by the seal, so the small tile's fits too. */
.ps-chair { position: absolute; left: 14%; top: 12%; width: 72%; height: 72%; pointer-events: none; user-select: none;
  filter: brightness(calc(.5 + var(--lit) * .5)) saturate(calc(.65 + var(--lit) * .35)); }
[dir='ltr'] .ps-chair { scale: -1 1; }
/* The salon is checking the transfer: the lens looks about, for as long as it waits (full motion only). */
:root[data-motion='full'] .bk-chair.searching .ps-coin .icon { animation: ch-search 2.6s ease-in-out infinite; }
/* The salon is on it: the stripes turn slowly, for as long as it waits (in full motion: at
   lite, an ambient loop is one too many, and the half-lit pole says "waiting" by itself). */
:root[data-motion='full'] .bk-pole.turning .ps-stripes { animation: ps-turn 3.2s linear infinite; }

/* .moment switches it on: two flickers (under the flash threshold), a whirl that settles
   on a whole turn, a glint across the glass, the coin. JS adds it only when motion is
   allowed; the resting styles above are its last frame. */
@media (prefers-reduced-motion: no-preference) {
  .bk-pole.moment { animation: pop .3s var(--ease-out) both; }
  .bk-pole.moment .ps-halo { animation: ps-power .7s linear .16s both; }
  .bk-pole.moment .ps-veil { animation: ps-veil .7s linear .16s both; }
  .bk-pole.moment .ps-light { animation: ps-fill .5s var(--ease-out) .2s both; }
  .bk-pole.moment .ps-stripes { animation: ps-whirl 1.2s cubic-bezier(.55, 0, .25, 1) .3s both, ps-turn 2.6s linear 1.5s 4; }
  .bk-pole.moment .ps-glint::before { animation: ps-glint .7s cubic-bezier(.4, 0, .6, 1) .7s both; }
  .bk-pole.moment .ps-coin { animation: ps-coin .55s var(--spring) .9s both; }
  .bk-pole.moment .ps-coin.c-check .icon > * { stroke-dasharray: 24; stroke-dashoffset: 24; animation: draw .45s var(--ease-out) 1.05s forwards; }
  /* The chair: its light comes on with the halo's flicker. */
  .bk-pole.moment .ps-chair { animation: ch-power .7s linear .16s both; }
  /* Lite: the light comes on without the flicker, the stripes turn twice, no glint. */
  :root[data-motion='lite'] .bk-pole.moment .ps-halo { animation: ps-on .35s ease-out .16s both; }
  :root[data-motion='lite'] .bk-pole.moment .ps-veil { animation: ps-off .35s ease-out .16s both; }
  :root[data-motion='lite'] .bk-pole.moment .ps-stripes { animation: ps-turn 2.6s linear .3s 2; }
  :root[data-motion='lite'] .bk-pole.moment .ps-glint::before { animation: none; }
  :root[data-motion='lite'] .bk-pole.moment .ps-chair { animation: ch-on .35s ease-out .16s both; }
}
@keyframes ps-power {
  0% { opacity: 0; } 14% { opacity: calc(var(--lit) * .55); } 22% { opacity: calc(var(--lit) * .15); } 40% { opacity: calc(var(--lit) * .85); }
  48% { opacity: calc(var(--lit) * .45); } 70% { opacity: var(--lit); } 100% { opacity: calc(var(--lit) * .8); }
}
@keyframes ps-veil {
  0% { opacity: 1; } 14% { opacity: calc(1 - var(--lit) * .55); } 22% { opacity: calc(1 - var(--lit) * .15); } 40% { opacity: calc(1 - var(--lit) * .85); }
  48% { opacity: calc(1 - var(--lit) * .45); } 70%, 100% { opacity: calc(1 - var(--lit)); }
}
@keyframes ps-on { from { opacity: 0; } }
@keyframes ps-off { from { opacity: 1; } }
@keyframes ps-fill { from { scale: 1 0; } }
/* 576px is twelve turns of 48px: the whirl ends where the calm turn begins. */
@keyframes ps-whirl { from { translate: 0 0; } to { translate: 0 calc(var(--pp) * 24); } }
@keyframes ps-turn { from { translate: 0 0; } to { translate: 0 calc(var(--pp) * 2); } }
@keyframes ps-glint { 0% { opacity: 0; translate: calc(var(--x-dir) * 30%) 0; } 15%, 85% { opacity: 1; } 100% { opacity: 0; translate: calc(var(--x-dir) * -30%) 0; } }
@keyframes ps-coin { from { opacity: 0; scale: .3; rotate: -30deg; } }
@keyframes ch-power {
  0% { filter: brightness(.42) saturate(.6); } 14% { filter: brightness(calc(.42 + var(--lit) * .4)) saturate(.8); } 22% { filter: brightness(.5) saturate(.65); }
  40% { filter: brightness(calc(.5 + var(--lit) * .45)) saturate(.9); } 48% { filter: brightness(.6) saturate(.75); }
  70%, 100% { filter: brightness(calc(.5 + var(--lit) * .5)) saturate(calc(.65 + var(--lit) * .35)); }
}
@keyframes ch-on { from { filter: brightness(.42) saturate(.6); } }
@keyframes ch-search { 0%, 100% { translate: 0 0; } 25% { translate: -1.5px -1px; } 50% { translate: 1px -1.8px; } 75% { translate: 1.5px .6px; } }

/* The landing's steel shears (shears()): drawn with the tips to +x and mirrored by
   --x-dir; the blades turn about the screw. Clippings fall from a point (.bx-hb). */
.bx-shears { position: absolute; }
.bx-arc { position: absolute; inset: 0; }
.bx-shears img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; transform-origin: 57.69% 50%; }
.bx-a { rotate: -7deg; }
.bx-b { rotate: 7deg; }
.bx-hb { position: absolute; left: 0; top: 0; }
.bx-clip { position: absolute; left: 0; top: 0; width: var(--hw); max-width: none; margin-left: calc(var(--hw) / -2); }

/* The ribbon cut (ribbonCut()): over a stage, the knot at --kx, --ky (the middle unless
   set). The shears come from the inline end with their tips on the knot. */
.bx-stage { position: absolute; inset: 0; z-index: 6; overflow: hidden; overflow: clip; pointer-events: none; --shw: 120px; --x-dir: 1; }
[dir='ltr'] .bx-stage { --x-dir: -1; }
@media (min-width: 1080px) { .bx-stage { --shw: 160px; } }
.bx-dim {
  position: absolute; inset: 0;
  background: radial-gradient(44% 34% at var(--kx, 50%) var(--ky, 50%), color-mix(in srgb, var(--light) 22%, transparent), transparent 72%), color-mix(in srgb, var(--bg) 82%, transparent);
  animation: bx-dim 2s linear both;
}
@keyframes bx-dim { 0% { opacity: 0; } 17%, 92% { opacity: 1; } 100% { opacity: 0; } }
/* Satin in the salon's accent: a lit top edge, two pinstripes in its main colour, a neon glow. */
.bx-rib {
  position: absolute; top: calc(var(--ky, 50%) - 12px); height: 24px;
  background: linear-gradient(transparent 4px, color-mix(in srgb, var(--primary) 70%, transparent) 4px 5px, transparent 5px 19px, color-mix(in srgb, var(--primary) 70%, transparent) 19px 20px, transparent 20px),
    linear-gradient(180deg, color-mix(in srgb, var(--accent), #fff 42%), var(--accent) 30%, color-mix(in srgb, var(--accent), #000 24%));
  box-shadow: 0 8px 18px -8px rgb(0 0 0 / .7), 0 0 22px -6px var(--light-glow);
}
.bx-rib.l { left: 0; width: var(--kx, 50%); transform-origin: 0 50%; animation: bx-rib-l .35s var(--ease-out) both; }
.bx-rib.r { left: var(--kx, 50%); right: 0; transform-origin: 100% 50%; animation: bx-rib-r .35s var(--ease-out) both; }
@keyframes bx-rib-l { from { translate: -100% 0; } }
@keyframes bx-rib-r { from { translate: 100% 0; } }
.bx-stage.cut .bx-rib.l { animation: bx-fall-l .9s cubic-bezier(.45, 0, .8, .5) forwards; }
.bx-stage.cut .bx-rib.r { animation: bx-fall-r .9s cubic-bezier(.45, 0, .8, .5) forwards; }
@keyframes bx-fall-l { 30% { rotate: 14deg; translate: 0 20px; } 100% { rotate: 26deg; translate: 0 220px; opacity: 0; } }
@keyframes bx-fall-r { 30% { rotate: -14deg; translate: 0 20px; } 100% { rotate: -26deg; translate: 0 220px; opacity: 0; } }
.bx-knot { position: absolute; left: calc(var(--kx, 50%) - 44px); top: calc(var(--ky, 50%) - 30px); width: 88px; height: 60px; max-width: none; filter: drop-shadow(0 6px 10px rgb(0 0 0 / .5)); animation: bx-pop .35s var(--spring) .3s both; }
@keyframes bx-pop { from { opacity: 0; scale: .6; } }
.bx-stage.cut .bx-knot { animation: bx-drop .8s cubic-bezier(.45, 0, .8, .5) forwards; }
@keyframes bx-drop { to { translate: 0 170px; rotate: 40deg; opacity: 0; } }
.bx-tips { position: absolute; left: var(--kx, 50%); top: var(--ky, 50%); width: 0; height: 0; }
.bx-cut {
  left: calc(var(--shw) * -.977); top: calc(var(--shw) * -48 / 260); width: var(--shw); aspect-ratio: 260 / 96;
  transform-origin: 97.7% 50%; scale: var(--x-dir) 1; rotate: calc(var(--x-dir) * 12deg); animation: bx-sh-in .5s var(--ease-out) .35s both;
}
@keyframes bx-sh-in { from { opacity: 0; translate: calc(var(--x-dir) * -70px) -80px; rotate: calc(var(--x-dir) * 34deg); } }
.bx-stage.out .bx-cut { animation: bx-sh-out .35s ease-in forwards; }
@keyframes bx-sh-out { to { opacity: 0; translate: calc(var(--x-dir) * -60px) -70px; rotate: calc(var(--x-dir) * 30deg); } }
/* The shop's sign behind the knot: it comes on as the ribbon falls, then fades with the room. */
.bx-pole { inset: calc(var(--ky, 50%) - 56px) auto auto calc(var(--kx, 50%) - 56px); width: 112px; height: 112px; opacity: 0; }
@media (min-width: 1080px) { .bx-pole { scale: 1.25; } }
.bx-stage.lit .bx-pole { opacity: 1; animation: bx-pole-in .4s var(--ease-out) both, bx-pole-out .5s ease 1.35s forwards; }
@keyframes bx-pole-in { from { opacity: 0; scale: .8; } }
@keyframes bx-pole-out { to { opacity: 0; } }
/* A ring of bulbs given to the cut lights one by one with the pole. */
.bulbs.lighting i.on { animation: bulb-on .7s linear both; animation-delay: calc(var(--i) * 45ms); }
/* Lite: no whirl or glint; a shorter room. Still: the last frame (the pole lit). */
.bx-stage[data-level='lite'] .bx-dim { animation-duration: 1.5s; }
.bx-stage[data-level='lite'] .bk-pole.moment .ps-stripes, .bx-stage[data-level='lite'] .bk-pole.moment .ps-glint::before { animation: none; }
.bx-stage[data-level='lite'] .bk-pole.moment .ps-halo { animation: ps-on .3s ease-out both; }
.bx-stage[data-level='lite'] .bk-pole.moment .ps-veil { animation: ps-off .3s ease-out both; }
.bx-stage[data-level='lite'].lit .bx-pole { animation: bx-pole-in .3s var(--ease-out) both, bx-pole-out .4s ease .9s forwards; }
.bx-stage.end :is(.bx-dim, .bx-rib, .bx-knot, .bx-tips) { display: none; }
.bx-stage.end .bx-pole { opacity: 1; }

/* ---------------------------------------------------------------- overlays */
.toast {
  position: fixed; z-index: 200; top: calc(14px + var(--safe-top)); left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px; width: max-content; max-width: calc(100vw - 32px); padding: 12px 18px 12px 16px; border-radius: 999px;
  background: rgb(26 26 32 / .94); color: #f5f5f7; border: 1px solid rgb(255 255 255 / .12);
  backdrop-filter: blur(18px) saturate(1.6); -webkit-backdrop-filter: blur(18px) saturate(1.6);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), var(--depth-3); font-size: 14.5px; font-weight: 500;
  animation: toast-in .5s var(--spring);
}
.toast .icon { width: 20px; height: 20px; color: #34d399; }
.toast .icon:not(.snip-glyph) > * { stroke-dasharray: 64; stroke-dashoffset: 64; animation: draw .6s var(--ease-out) .12s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.toast.error .icon { color: #ff6b6b; }
/* Booked, a walk-in recorded, a deposit in: the barber's scissors snip twice, in the light. */
.toast.done .icon.snip-glyph { flex: none; overflow: visible; color: var(--light-hi); filter: var(--glyph-glow); }
.snip-glyph g { transform-box: view-box; transform-origin: 256px 259px; }
:root:not([data-motion='still']) .toast.done .snip-glyph .a { animation: snip-a .15s var(--ease-press) .15s 4 alternate; }
:root:not([data-motion='still']) .toast.done .snip-glyph .b { animation: snip-b .15s var(--ease-press) .15s 4 alternate; }
@keyframes snip-a { to { rotate: -22deg; } }
@keyframes snip-b { to { rotate: 22deg; } }
.toast.out { opacity: 0; transform: translate(-50%, -12px); transition: opacity .25s, transform .25s; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -18px) scale(.9); } }
/* In the studio the confirmation rises where the work was saved: the bottom, where
   the savebar was, above the tab bar; never over the header's salon name. */
[data-theme='studio'] .toast {
  top: auto; bottom: calc(24px + var(--safe-bottom)); color: var(--text);
  background: color-mix(in srgb, var(--surface-3) 92%, transparent); border-color: var(--light-line);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), var(--depth-3), 0 0 40px -14px var(--light-glow); animation-name: toast-up;
}
[data-theme='studio'] .toast .icon { color: var(--ok); }
[data-theme='studio'] .toast.error { border-color: color-mix(in srgb, var(--danger) 45%, transparent); }
[data-theme='studio'] .toast.error .icon { color: var(--danger); }
[data-theme='studio'] body:has(.sched-dock) > .toast { bottom: calc(var(--tabbar) + 24px + var(--safe-bottom)); }
/* Clear of the tab bar's raised walk-in too. */
[data-theme='studio'] body:has(.s-tabbar) > .toast { bottom: calc(var(--tabbar) + 36px + var(--safe-bottom)); }
[data-theme='studio'] body:has(> .sheet-backdrop) > .toast { bottom: calc(96px + var(--safe-bottom)); }
[data-theme='studio'] .toast.out { transform: translate(-50%, 10px) scale(.96); }
@keyframes toast-up { from { opacity: 0; transform: translate(-50%, 18px) scale(.94); } }
/* A toast that offers a way back (Undo): a rounded card, since the message may take two lines. */
.toast.has-act { padding-block: 8px; padding-inline: 16px 8px; border-radius: 20px; }
.toast.has-act > span { flex: 1 1 auto; min-width: 0; line-height: 1.45; }
.toast .toast-act { flex: none; height: 36px; margin-inline-start: 4px; padding: 0 14px; border-radius: 12px; background: rgb(255 255 255 / .08); border: 1px solid rgb(255 255 255 / .16); color: inherit; font: inherit; font-weight: 600; cursor: pointer; transition: background-color .2s; }
[data-theme='studio'] .toast .toast-act { background: var(--surface-2); border-color: var(--line-2); color: var(--text); }
[data-theme='studio'] .toast .toast-act:hover { background: var(--surface); }

.sheet-backdrop {
  position: fixed; inset: 0; z-index: 100; display: flex; align-items: flex-end; justify-content: center;
  background: rgb(0 0 0 / .55); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); animation: fade .25s ease;
}
.sheet {
  position: relative; width: 100%; max-width: 560px; max-height: 94dvh; display: flex; flex-direction: column;
  background: var(--pane-edge), var(--bg-2); border: 1px solid var(--line-2); border-bottom: 0; border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), 0 -20px 60px -10px rgb(0 0 0 / .6); animation: sheet-in .5s var(--ease-out);
}
/* The dialog itself takes focus when it opens (so keys act inside it); it needs no ring. */
.sheet:focus-visible { outline: none; }
.sheet.closing { transform: translateY(100%); transition: transform .3s var(--ease-out); }
.sheet-backdrop.closing { opacity: 0; transition: opacity .3s; }
@keyframes sheet-in { from { transform: translateY(100%); } }
.sheet-handle { width: 40px; height: 5px; border-radius: 3px; background: var(--line-2); margin: 8px auto 0; flex: none; }
.sheet-head { display: flex; align-items: center; gap: 12px; padding: 8px 20px 12px; }
.sheet-head h2 { flex: 1; font-size: 20px; }
.sheet-body { flex: 1 1 auto; overflow-y: auto; padding: 4px 20px 24px; overscroll-behavior: contain; }
.sheet-foot { display: flex; gap: 10px; padding: 12px 20px calc(12px + var(--safe-bottom)); border-top: 1px solid var(--line); background: var(--glass); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); }
.sheet-foot .btn-primary { flex: 1; }
.sheet.tall { height: 94dvh; }
@media (max-width: 699px) {
  /* Over a bottom sheet the free space is the dimmed band above it, not the sheet's
     last rows (a confirm question, the chips just saved): the toast drops in there.
     Once the sheet is closing, it rises at the usual bottom spot instead. */
  [data-theme='studio'] body:has(> .sheet-backdrop:not(.closing)) > .toast { top: calc(12px + var(--safe-top)); bottom: auto; animation-name: toast-in; }
  [data-theme='studio'] body:has(> .sheet-backdrop:not(.closing)) > .toast.out { transform: translate(-50%, -12px); }
  /* Keep that band clear on tall sheets too (12px + the ~49px toast + a gap). */
  [data-theme='studio'] .sheet { max-height: calc(100dvh - 68px - var(--safe-top)); }
  [data-theme='studio'] .sheet.tall { height: calc(100dvh - 68px - var(--safe-top)); }
}
@media (min-width: 700px) {
  .sheet-backdrop { align-items: center; padding: 24px; }
  .sheet { border-radius: var(--r-xl); border-bottom: 1px solid var(--line-2); max-height: 88dvh; animation: pop .35s var(--ease-out); }
  .sheet.tall { height: auto; }
  .sheet.closing { transform: scale(.96); opacity: 0; transition: transform .2s, opacity .2s; }
  .sheet-handle { display: none; }
  .sheet-head { padding-top: 18px; }
}

.savebar {
  position: fixed; z-index: 60; inset-inline: 12px; bottom: calc(var(--tabbar) + 22px + var(--safe-bottom));
  max-width: 536px; margin: 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 16px;
  border-radius: 20px; background: color-mix(in srgb, var(--bg-2) 88%, transparent); border: 1px solid var(--light-line);
  backdrop-filter: blur(24px) saturate(1.6); -webkit-backdrop-filter: blur(24px) saturate(1.6);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), var(--depth-3), 0 0 40px -12px var(--light-glow); animation: savebar-in .45s var(--spring);
}
[dir='rtl'] .savebar { padding: 8px 16px 8px 8px; }
/* Unsaved changes: the savebar takes the tab bar's place instead of stacking above
   it, and the page leaves room so its last section can still be reached. */
.s-tabbar { transition: transform .45s var(--ease-out), opacity .3s, visibility 0s; }
/* Once it has slid away it leaves the tab order and the accessibility tree too. */
body:has(> .savebar) .s-tabbar { transform: translateY(calc(100% + 24px)); opacity: 0; pointer-events: none; visibility: hidden; transition: transform .45s var(--ease-out), opacity .3s, visibility 0s .45s; }
@media (max-width: 1079px) {
  .savebar { bottom: calc(12px + var(--safe-bottom)); height: var(--tabbar); max-width: 520px; border-radius: 26px; padding-block: 10px; }
}
body:has(> .savebar) .s-page { padding-bottom: calc(var(--tabbar) + 64px + var(--safe-bottom)); }
.savebar .grow { display: flex; align-items: center; gap: 8px; }
.savebar .grow::before { content: ''; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--warn); box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 18%, transparent); }
.savebar .grow { font-size: 14.5px; font-weight: 500; }
.savebar .btn { height: 44px; }
@keyframes savebar-in { from { opacity: 0; transform: translateY(20px) scale(.96); } }

.confetti { position: fixed; inset: 0; z-index: 300; width: 100vw; height: 100vh; pointer-events: none; }

/* ==========================================================================
   Studio shell
   ========================================================================== */
.studio { position: relative; min-height: 100dvh; isolation: isolate; }
/* The room at night: a still light from the ceiling and a fainter one at the start side.
   They drift only in full motion on the pages about the salon's look (the hub, the brand,
   the setup guide), never on Home or Bookings, the screens opened all day; and only on a
   wide screen: on a phone those pages' glass bars (the guide's top and foot, the tab bar)
   sit over the light, and a moving light under them is blurred again at every frame. */
.studio::before, .studio::after { content: ''; position: fixed; z-index: -1; width: 90vmax; height: 90vmax; border-radius: 50%; pointer-events: none; }
.studio::before { top: -55vmax; inset-inline-end: -40vmax; background: radial-gradient(circle, color-mix(in srgb, var(--glow-1) 20%, transparent), transparent 62%); }
.studio::after { top: -50vmax; inset-inline-start: -50vmax; background: radial-gradient(circle, color-mix(in srgb, var(--glow-3) 12%, transparent), transparent 62%); }
@media (min-width: 1080px) {
  :root[data-motion='full'] .studio:is([data-page='salon'], [data-page='brand'], [data-page='setup'])::before { animation: drift 26s ease-in-out infinite alternate; }
}
.s-main { min-width: 0; }
.s-header {
  position: sticky; top: 0; z-index: 50; display: flex; align-items: center; gap: 10px;
  padding: calc(10px + var(--safe-top)) 16px 10px; transition: background-color .3s, border-color .3s;
  border-bottom: 1px solid transparent;
}
.s-header.scrolled { background: var(--glass); border-color: var(--line); backdrop-filter: blur(20px) saturate(1.6); -webkit-backdrop-filter: blur(20px) saturate(1.6); }
.s-header .icon-btn { width: 42px; height: 42px; border-radius: 14px; background: var(--surface); }
.identity { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; }
.identity .app-icon { --s: 38px; }
.identity .name { font-weight: 600; font-size: 15.5px; line-height: 1.2; }
.identity .sub { font-size: 12px; color: var(--text-3); line-height: 1.3; }
/* The host reads left to right but sits under the name, on the name's side. */
[dir='rtl'] .identity .sub { text-align: right; }

.s-page { max-width: 600px; margin: 0 auto; padding: 8px 16px calc(var(--tabbar) + 48px + var(--safe-bottom)); }
.s-title { font-size: 30px; font-weight: 700; line-height: 1.2; }
.s-sub { color: var(--text-2); font-size: 15px; margin-top: 6px; max-width: 46ch; }
.s-head { display: flex; align-items: center; gap: 10px; margin: 10px 2px 22px; }
.s-head .head-add .icon { width: 17px; height: 17px; }
.s-head .grow > .s-title { display: flex; align-items: center; gap: 10px; }

.s-tabbar {
  position: fixed; z-index: 55; bottom: calc(12px + var(--safe-bottom)); inset-inline: 12px; max-width: 520px; margin: 0 auto;
  height: var(--tabbar); padding: 6px; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 2px;
  border-radius: 26px; background: var(--pane-edge), color-mix(in srgb, var(--bg-2) 88%, transparent); border: 1px solid var(--line-2);
  backdrop-filter: blur(24px) saturate(1.8); -webkit-backdrop-filter: blur(24px) saturate(1.8);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), var(--depth-3);
}
.s-tab {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border-radius: 20px; color: var(--text-3); font-size: 11.5px; font-weight: 500; transition: color .25s, background-color .25s;
}
.s-tab.active > span:not([class]) { font-weight: 600; }
.s-tab .icon { width: 23px; height: 23px; transition: transform .35s var(--spring); }
.s-tab:active .icon { transform: scale(.88); }
.s-tab { isolation: isolate; }
.s-tab.active { color: var(--text); }
.s-tab.active .icon { color: var(--light-hi); filter: drop-shadow(0 0 8px var(--light-glow)); }
/* The active highlight is one element that slides between tabs (view transitions): a pane
   of glass with the tab's bulb, a short lit tube at its top, riding along with it. */
.nav-pill { position: absolute; inset: 0; z-index: -1; border-radius: 20px; background: color-mix(in srgb, var(--surface-3) 80%, transparent); box-shadow: inset 0 1px 0 var(--rim-hi), inset 0 0 0 1px var(--line-2); pointer-events: none; }
.s-tab .nav-pill { view-transition-name: tab-pill; }
.s-tab .nav-pill::after { content: ''; position: absolute; top: 0; left: 50%; width: 14px; height: 3px; margin-left: -7px; border-radius: 0 0 3px 3px; background: var(--light-hi); box-shadow: 0 0 10px var(--light-glow), 0 0 3px var(--light); }
.s-tabbar { view-transition-name: tabbar; }
.s-tab .badge-dot { position: absolute; top: 9px; inset-inline-end: calc(50% - 17px); width: 8px; height: 8px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px var(--bg-2); }
.s-tab > span:not([class]) { white-space: nowrap; }
/* The walk-in: the tab bar's raised centre, an action rather than a page. */
.s-tab-walkin { padding: 0; background: none; border: 0; color: var(--text); cursor: pointer; }
/* A raised disc with the main action's neon rim. */
.s-tab-walkin .act {
  display: grid; place-items: center; width: 52px; height: 52px; margin-top: -26px; border-radius: 50%;
  background: var(--grad, var(--brand)); color: var(--on-brand);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .3), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 22px -4px var(--light-glow), 0 12px 28px -10px var(--cta-glow);
  transition: transform var(--t-release) var(--spring-soft), box-shadow .25s;
}
.s-tab-walkin .act .icon { width: 24px; height: 24px; }
.s-tab-walkin:active .act { transform: translateY(1px) scale(.94); transition-duration: var(--t-press); transition-timing-function: var(--ease-press); }
.s-tab-walkin:active .act .icon { transform: none; }
.s-tab-walkin:focus-visible { outline: none; }
.s-tab-walkin:focus-visible .act { outline: 2px solid var(--light); outline-offset: 3px; }
.badge-count { position: absolute; top: 5px; inset-inline-end: calc(50% - 22px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 99px; display: grid; place-items: center; font-size: 10.5px; font-weight: 700; color: #fff; background: var(--danger); box-shadow: 0 0 0 2px var(--bg-2); animation: pop .4s var(--spring); }

.s-side, .s-preview { display: none; }

/* ==========================================================================
   Home
   ========================================================================== */
/* The day's head: the date, a greeting by name, open or closed. */
.home-head { margin: 10px 2px 0; }
.home-head .home-date { font-size: 13.5px; color: var(--text-2); }
.home-head .home-title { margin-top: 4px; font-size: 26px; font-weight: 700; line-height: 1.25; }
.home-open { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; margin-top: 10px; min-height: 30px; padding: 4px 12px; border-radius: 99px; background: var(--surface); border: 1px solid var(--line); font-size: 13px; color: var(--text-2); }
.home-open .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); }
.home-open.open { color: var(--text); }
.home-open.open .dot { background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 22%, transparent); }
/* Not opened yet: no green light, the way to the opening. */
.home-open.soon { background: var(--surface-2); color: var(--text-2); text-decoration: none; }
.home-open.soon .icon { width: 15px; height: 15px; color: var(--text-3); flex: none; }
a.home-open.soon:hover { color: var(--text); border-color: var(--line-2); }

/* A walk-in and a new booking, one tap each. */
.home-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 18px; }
.home-actions .btn { height: 52px; min-width: 0; padding-inline: 12px; }
.home-actions .btn > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* What needs the owner: one line each, with the one thing to do about it. */
.home-attention:not(:has(.att-item)) { display: none; }
.att-item { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 12px; row-gap: 10px; padding: 14px; }
.att-item + .att-item { border-top: 1px solid var(--line); }
.att-item .tile { width: 42px; height: 42px; border-radius: 13px; }
.att-item .tile .icon { width: 20px; height: 20px; }
.att-item .title { font-weight: 600; line-height: 1.4; }
.att-item .att-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px 14px; }
.att-item .sub { margin-top: 1px; font-size: 13px; line-height: 1.45; color: var(--text-2); }
.att-item > .link-btn { padding-inline: 4px; }
.att-item.temp-pw .tile, .att-item.off .tile { background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); }
.att-item.deposits .tile { background: color-mix(in srgb, var(--info) 14%, transparent); color: var(--info); }
/* Its long button goes under the text on a phone (not under the icon). */
.att-item.temp-pw > .btn { grid-column: 2 / -1; justify-self: start; }
@media (min-width: 560px) {
  .att-item.temp-pw > .btn { grid-column: auto; }
}

/* Until the salon opens: the setup guide in one mirror. The salon's icon in its ring of
   bulbs (one lit per part done), how far along, the next step lit, and the way back in. */
.guide-card { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 16px 16px; margin-top: 22px; padding: 18px 18px 16px; }
.guide-mirror { width: 100px; height: 100px; margin: 0; --rd: 46px; --bs: 5px; }
.guide-mirror .app-icon { --s: 62px; border-radius: 18px; }
.guide-mirror .gs-halo { inset: -8%; }
.guide-txt { min-width: 0; }
.guide-txt h2 { font-size: 19px; font-weight: 700; line-height: 1.3; }
.guide-line { margin-top: 4px; font-size: 13.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.guide-next { display: flex; align-items: center; gap: 7px; margin-top: 10px; font-size: 13.5px; font-weight: 600; color: var(--light-hi); }
.guide-next .icon { flex: none; width: 16px; height: 16px; color: var(--light); filter: var(--glyph-glow); }
.guide-next span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.guide-go { grid-column: 1 / -1; height: 52px; }
/* Ready: every bulb lit, the room's light a little warmer under it. */
.guide-card.ready { box-shadow: var(--depth-2), 0 22px 60px -24px var(--light-glow); }
.guide-card.ready .gs-halo { background: radial-gradient(closest-side, color-mix(in srgb, var(--bulb-core) 20%, transparent), color-mix(in srgb, var(--light) 16%, transparent) 60%, transparent); }

/* The visits still to come today. */
.today-section .section-head h2 { display: flex; align-items: center; gap: 8px; }
.today-section .section-head .count { min-width: 24px; height: 24px; padding: 0 7px; font-size: 12.5px; }
.today-list { list-style: none; margin: 0; padding: 0; }
.today-list > li + li { border-top: 1px solid var(--line); }
.today-row { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 12px 14px; color: var(--text); transition: background-color .2s, scale var(--t-release) var(--spring-soft); }
a.today-row:hover { background: var(--surface-2); }
.today-row:focus-visible { outline-offset: -2px; }
.today-row .t { flex: none; min-width: 64px; font-size: 17px; font-weight: 400; font-variant-numeric: tabular-nums; }
.today-row.live .t { color: var(--now); }
.today-row .nm { display: block; font-weight: 600; line-height: 1.4; }
.today-row .meta { display: flex; align-items: center; gap: 6px; min-width: 0; margin-top: 2px; font-size: 13px; color: var(--text-2); }
.today-row .meta > .truncate { min-width: 0; }
.today-row .svc-ic { width: 15px; height: 15px; color: var(--violet, var(--brand)); }
.today-row .sep { color: var(--text-3); }
.today-row .who { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.today-row .who .avatar { width: 18px; height: 18px; font-size: 9px; }
.today-row .live-tag { flex: none; font-size: 12.5px; }
.today-row .pill { flex: none; height: 24px; padding: 0 9px; font-size: 12px; }
.today-row.skel-row .grow { display: block; }
.today-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 22px 18px; text-align: center; color: var(--text-2); }
.today-empty .tile { width: 44px; height: 44px; border-radius: 14px; }
.today-failed { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 16px 18px; }

/* The salon's link, to copy or share. */
.link-row { display: flex; align-items: center; gap: 12px; margin-top: 28px; padding: 12px 12px 12px 14px; }
[dir='rtl'] .link-row { padding: 12px 14px 12px 12px; }
.link-row .tile { width: 42px; height: 42px; border-radius: 13px; }
.link-row .tile .icon { width: 20px; height: 20px; }
.link-row .lbl { font-size: 12.5px; color: var(--text-3); }
.link-row .url { display: block; margin-top: 1px; font-size: 14.5px; font-weight: 600; text-align: start; }
[dir='rtl'] .link-row .url { text-align: end; }
.link-row .icon-btn { flex: none; width: 40px; height: 40px; border-radius: 12px; }

/* ==========================================================================
   Guided setup (manage-setup.js): a page of its own, one calm question at a time.
   On a phone a glass bar holds where he is and the pole that fills; on a wide screen
   a rail of mirror bulbs and steps sits beside the question, and the live phone beside
   that. Every field saves itself: a small chip says so.
   ========================================================================== */
.studio.focus .s-page { max-width: 640px; padding: 0 16px calc(130px + var(--safe-bottom)); }
.gs { position: relative; }
.gs-top {
  position: sticky; top: 0; z-index: 50; margin: 0 -16px; padding: calc(8px + var(--safe-top)) 16px 12px;
  background: var(--pane-edge), var(--glass); border-bottom: 1px solid var(--line);
  backdrop-filter: blur(22px) saturate(1.6); -webkit-backdrop-filter: blur(22px) saturate(1.6);
}
.gs-top-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; align-items: center; gap: 4px; min-height: 48px; }
.gs-top .pole-bar { margin-top: 6px; }
.gs-where { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 4px 6px 4px 2px; background: none; border: 0; border-radius: 14px; color: var(--text); text-align: start; cursor: pointer; }
[dir='rtl'] .gs-where { padding: 4px 2px 4px 6px; }
.gs-where .app-icon { --s: 32px; border-radius: 10px; box-shadow: 0 0 0 1px rgb(255 255 255 / .1), 0 0 18px -6px var(--light-glow); }
.gs-where-txt { display: grid; min-width: 0; line-height: 1.25; }
.gs-where-n { font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.gs-where-t { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 15px; font-weight: 600; }
.gs-where .chev { flex: none; width: 16px; height: 16px; color: var(--text-3); }
.gs-top .icon-btn { width: 40px; height: 40px; border-radius: 12px; color: var(--text-2); }

/* The saving chip: a pulsing light while it saves, a check drawn once saved (then gone),
   the failure with its retry. Hidden while there is nothing to say. */
/* Its place is kept while it is idle (hidden, not gone), wide enough for "saving" and
   "saved": a save and its fading 2s later move nothing beside it in the bar. */
.gs-save { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 84px; height: 30px; padding-inline: 9px 11px; border-radius: 99px; font-size: 12.5px; font-weight: 500; white-space: nowrap; color: var(--text-2); background: color-mix(in srgb, var(--surface-2) 80%, transparent); border: 1px solid var(--line); visibility: hidden; opacity: 0; transition: opacity .25s, visibility 0s .25s; }
.gs-save:is(.saving, .saved, .failed) { visibility: visible; opacity: 1; transition: opacity .25s; animation: pop .3s var(--ease-out) both; }
.gs-save .mk { position: relative; display: grid; place-items: center; width: 14px; height: 14px; }
.gs-save .mk i { width: 7px; height: 7px; border-radius: 50%; background: var(--light); box-shadow: 0 0 8px var(--light-glow); }
.gs-save .mk .icon { display: none; width: 15px; height: 15px; color: var(--ok); stroke-width: 2.4; }
.gs-save.saving .mk i { animation: gs-pulse 1s ease-in-out infinite alternate; }
.gs-save.saved { color: var(--text); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.gs-save.saved .mk i { display: none; }
.gs-save.saved .mk .icon { display: block; }
.gs-save.saved .mk .icon > * { stroke-dasharray: 24; stroke-dashoffset: 24; animation: draw .45s var(--ease-out) forwards; }
.gs-save.failed { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.gs-save.failed .mk i { background: var(--danger); box-shadow: 0 0 8px color-mix(in srgb, var(--danger) 60%, transparent); }
.gs-retry { display: none; padding: 0 2px; background: none; border: 0; color: var(--light-hi); font: inherit; font-weight: 600; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.gs-save.failed .gs-retry { display: inline; }
@keyframes gs-pulse { from { opacity: .35; scale: .8; } }

/* The step: a folio, the giant outlined numeral behind it, the question and its line. */
/* The welcome's aurora and the giant numeral may reach past the column: never the page. */
.gs-body { padding-top: 26px; overflow-x: clip; }
.gs-body-in { position: relative; isolation: isolate; }
.gs-num {
  position: absolute; z-index: -1; top: -12px; inset-inline-end: -4px; display: grid; height: 1em; overflow: hidden; overflow: clip; pointer-events: none;
  font-size: 88px; font-weight: 200; line-height: 1; font-variant-numeric: tabular-nums;
  color: transparent; -webkit-text-stroke: 1px color-mix(in srgb, var(--light) 55%, transparent); opacity: .6; filter: drop-shadow(0 0 12px var(--light-glow));
}
.gs-num b { grid-area: 1 / 1; font-weight: inherit; direction: ltr; unicode-bidi: isolate; }
.gs-step.fwd { animation: bk-from-end .45s var(--ease-out); }
.gs-step.back { animation: bk-from-start .45s var(--ease-out); }
[dir='rtl'] .gs-step.fwd { animation-name: bk-from-start; }
[dir='rtl'] .gs-step.back { animation-name: bk-from-end; }
.gs-step > .folio { margin-bottom: 14px; }
.gs-title { font-size: 26px; font-weight: 700; line-height: 1.3; max-width: 24ch; text-wrap: balance; }
/* The question keeps clear of the numeral behind it. */
.gs-step > .gs-title { padding-inline-end: 88px; }
.gs-title:focus { outline: none; }
.gs-sub { margin-top: 8px; max-width: 46ch; font-size: 15px; line-height: 1.65; color: var(--text-2); }
.gs-step > .gs-sub + * { margin-top: 24px; }
.gs-h { margin: 26px 2px 12px; font-size: 15px; font-weight: 600; }
.gs-note { display: flex; align-items: flex-start; gap: 8px; margin-top: 18px; font-size: 13px; line-height: 1.55; color: var(--text-3); }
.gs-note .icon { flex: none; width: 16px; height: 16px; margin-top: 2px; color: var(--light); filter: var(--glyph-glow); }

/* The foot: Back, and Next naming the step it goes to. On a phone it is a glass bar on the
   screen's floor; Skip (optional steps) floats just above it. */
.gs-foot {
  position: fixed; z-index: 55; inset-inline: 0; bottom: 0; padding: 10px 16px calc(10px + var(--safe-bottom));
  background: var(--pane-edge), color-mix(in srgb, var(--bg-2) 86%, transparent); border-top: 1px solid var(--line-2);
  backdrop-filter: blur(24px) saturate(1.7); -webkit-backdrop-filter: blur(24px) saturate(1.7); box-shadow: 0 -18px 40px -24px rgb(0 0 0 / .8);
}
.gs-foot-in { position: relative; display: flex; align-items: center; gap: 10px; max-width: 608px; margin: 0 auto; }
.gs-back { width: 52px; height: 52px; border-radius: 50%; }
.gs-next { flex: 1; min-width: 0; height: 54px; }
.gs-next > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gs-skip { position: absolute; bottom: calc(100% + 18px); left: 50%; translate: -50% 0; padding: 6px 14px; border-radius: 99px; background: var(--glass); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
:root[data-motion='lite'] :is(.gs-top, .gs-foot) { -webkit-backdrop-filter: none; backdrop-filter: none; background: color-mix(in srgb, var(--bg-2) 96%, transparent); }
/* Confirmations rise clear of the foot (and of the preview button beside it). */
[data-theme='studio'] body:has(.gs-foot):not(:has(> .sheet-backdrop)) > .toast { bottom: calc(96px + var(--safe-bottom)); }

/* The mirror: the salon's icon in its ring of bulbs, one lit per part done. */
.gs-mirror { position: relative; display: grid; place-items: center; width: 132px; height: 132px; margin: 0 auto; --rd: 60px; --bs: 6px; }
.gs-mirror::before {
  content: ''; position: absolute; inset: 4px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 210deg, var(--neon-a), color-mix(in srgb, var(--neon-a) 10%, transparent) 22%, var(--neon-b) 50%, color-mix(in srgb, var(--neon-b) 10%, transparent) 76%, var(--neon-a));
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 1.5px), #000 calc(100% - 1px)); mask: radial-gradient(closest-side, transparent calc(100% - 1.5px), #000 calc(100% - 1px)); opacity: .7;
}
.gs-halo { position: absolute; inset: -18%; z-index: -1; border-radius: 50%; pointer-events: none; background: radial-gradient(closest-side, color-mix(in srgb, var(--light) 26%, transparent), transparent); }
.gs-mirror .app-icon { --s: 84px; border-radius: 24px; box-shadow: 0 0 0 1px rgb(255 255 255 / .14), 0 16px 34px -12px rgb(0 0 0 / .8), 0 0 36px -8px var(--light-glow); }
.gs-bulbs i { transition: background-color .4s, box-shadow .4s; }

/* The welcome: the mirror large, in a soft aurora; three phases on one lit line. */
.gs-welcome { position: relative; display: flex; flex-direction: column; align-items: center; padding-top: 18px; text-align: center; }
.gs-mirror.big { width: 236px; height: 236px; margin-bottom: 22px; --rd: 106px; --bs: 8px; }
.gs-mirror.big .app-icon { --s: 128px; border-radius: 34px; }
.gs-mirror.big .gs-halo { inset: -6%; background: radial-gradient(closest-side, color-mix(in srgb, var(--light) 30%, transparent), color-mix(in srgb, var(--neon-b) 10%, transparent) 62%, transparent); }
.gs-aura { position: absolute; inset: -46% -60%; z-index: -2; pointer-events: none; opacity: .8;
  background: radial-gradient(40% 36% at 30% 40%, color-mix(in srgb, var(--glow-1, var(--light)) 22%, transparent), transparent 70%), radial-gradient(38% 34% at 72% 62%, color-mix(in srgb, var(--glow-3, var(--light)) 18%, transparent), transparent 70%); }
.gs-kicker { font-size: 14px; font-weight: 500; color: var(--light-hi); text-shadow: 0 0 18px var(--light-glow); }
:lang(en) .gs-kicker { text-transform: uppercase; letter-spacing: .14em; font-size: 12.5px; }
.gs-welcome .gs-title { margin: 8px auto 0; font-size: 29px; max-width: 18ch; }
.gs-welcome .gs-sub { margin-inline: auto; max-width: 36ch; }
.gs-phases { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; width: 100%; max-width: 420px; margin: 28px auto 0; padding: 0; list-style: none; }
/* The line the three ride on: the pole's light, faint, through their tiles. */
.gs-phases::before { content: ''; position: absolute; top: 23px; inset-inline: 16.6%; height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--neon-a), var(--neon-b)); opacity: .35; box-shadow: 0 0 10px var(--light-glow); }
.gs-phase { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; line-height: 1.4; color: var(--text-2); }
.gs-phase .tile { width: 46px; height: 46px; border-radius: 50%; background: radial-gradient(120% 120% at 30% 0, var(--light-wash), transparent 60%), var(--surface); box-shadow: inset 0 1px 0 var(--rim-hi), 0 0 0 1px var(--line-2), 0 0 20px -8px var(--light-glow); }
.gs-welcome .gs-note { justify-content: center; margin-top: 26px; }
.gs-lang { margin-top: 8px; }

/* The password: the sign-in's eye, the rule under it, a green edge once it is his own. */
.gs-pw .f + .f { margin-top: 12px; }
.gs-pw-bulbs { display: flex; gap: 8px; margin: 14px 4px 0; }
.gs-pw-bulbs i { width: 8px; height: 8px; border-radius: 50%; background: var(--bulb-off); transition: background-color .25s, box-shadow .25s; }
.gs-pw-bulbs i.on { background: var(--bulb-core); box-shadow: 0 0 8px 1px var(--bulb-glow); }
.gs-pw-bulbs.full i { background: color-mix(in srgb, var(--ok), #fff 40%); box-shadow: 0 0 8px 1px color-mix(in srgb, var(--ok) 55%, transparent); }
.gs-pw .f.ok > input { border-color: color-mix(in srgb, var(--ok) 60%, transparent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 14%, transparent); }
.gs-done-card { display: flex; align-items: center; gap: 14px; }
.gs-done-card .tile { color: var(--ok); }
.gs-done-card p { margin-top: 2px; font-size: 13.5px; color: var(--text-2); }

/* Name and logo: the name, its English fold, then two choices (his logo, or the mark). */
.gs-identity .gs-fold { margin-top: 6px; }
.gs-identity .fold > .fold-inner { padding: 10px 4px 4px; margin: 0 -4px -4px; }
.f.gs-name > .hint { display: none; }
.f.gs-name.invalid > .hint { display: block; color: var(--danger); }
.gs-logo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.gs-choice {
  position: relative; isolation: isolate; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 18px 12px 16px; border-radius: 22px; text-align: center;
  background: var(--pane-edge), var(--pane-sheen), var(--surface); border: 1.5px solid var(--line); box-shadow: var(--depth-1);
  transition: border-color .25s, box-shadow .3s, transform var(--t-release) var(--spring-soft);
}
.gs-choice-hit { position: absolute; inset: -1.5px; z-index: 1; border-radius: inherit; background: none; border: 0; cursor: pointer; }
.gs-choice-hit:focus-visible { outline: 2px solid var(--light); outline-offset: 2px; }
.gs-choice:has(> .gs-choice-hit:active) { transform: scale(.975); transition-duration: var(--t-press); transition-timing-function: var(--ease-press); }
.gs-choice.on {
  border-color: var(--light); background: radial-gradient(100% 70% at 50% 0%, var(--light-wash), transparent 70%), var(--pane-edge), var(--surface);
  box-shadow: var(--depth-1), 0 0 0 1px var(--light-line), 0 0 30px -12px var(--light-glow);
}
.gs-choice.on::after {
  content: ''; position: absolute; top: 12px; inset-inline-end: 12px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--light) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0918' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 14px no-repeat;
  box-shadow: 0 0 12px var(--light-glow); animation: pop .35s var(--spring);
}
.gs-choice-art { display: grid; place-items: center; height: 80px; margin-bottom: 8px; }
.gs-choice-art .app-icon { --s: 72px; border-radius: 20px; box-shadow: 0 0 0 1px rgb(255 255 255 / .12), 0 12px 26px -12px rgb(0 0 0 / .8); }
.gs-logo-empty { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 20px; border: 1.5px dashed var(--line-2); color: var(--text-3); }
.gs-logo-empty .icon { width: 26px; height: 26px; }
.gs-choice b { font-size: 15px; font-weight: 600; }
.gs-choice > span { font-size: 12.5px; line-height: 1.45; color: var(--text-2); }
.gs-choice-acts { position: relative; z-index: 2; display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 10px; }
.gs-choice-acts .btn { height: 36px; padding-inline: 12px; font-size: 13px; }
/* A logo on its way up: a scan of light passes over it. */
.app-icon.uploading::after { content: ''; position: absolute; inset-inline: 0; top: 0; height: 40%; background: linear-gradient(transparent, color-mix(in srgb, var(--light) 50%, transparent), transparent); animation: gs-scan 1.1s var(--ease-out) infinite; }
@keyframes gs-scan { from { translate: 0 -100%; } to { translate: 0 260%; } }

/* Colours: on a phone the salon's app sits over the palettes (wider screens have the live phone). */
.gs-stage { display: grid; justify-items: center; margin-bottom: 18px; padding: 18px 0 14px; border-radius: 28px; border: 1px solid var(--line);
  background: radial-gradient(60% 50% at 50% 40%, color-mix(in srgb, var(--accent-lift) 22%, transparent), transparent 75%), var(--surface); }
.gs-look .scroller.palettes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 0; padding: 0; overflow: visible; -webkit-mask-image: none; mask-image: none; animation: none; }
.gs-look .palette { width: auto; }

/* The menu: a row per service, ticked and priced; a saved price says so under its name. */
.gs-menu.card { padding: 2px 14px; }
.gs-menu + .gs-menu { margin-top: 12px; }
.gs-menu .tpl-row { padding: 12px 0; }
.tpl-row .tpl-name { font-weight: 500; line-height: 1.4; }
.tpl-row .link-like { display: block; max-width: 100%; padding: 0; background: none; border: 0; color: inherit; font: inherit; font-weight: 500; text-align: start; cursor: pointer; text-decoration: underline dotted transparent; text-underline-offset: 4px; transition: text-decoration-color .2s; }
.tpl-row .link-like:hover { text-decoration-color: var(--text-3); }
.gs-saved-tag { display: none; align-items: center; gap: 3px; margin-inline-start: 8px; font-size: 12px; font-weight: 500; color: var(--ok); }
.gs-saved-tag .icon { width: 13px; height: 13px; stroke-width: 2.6; }
.tpl-row.saved .gs-saved-tag { display: inline-flex; animation: pop .35s var(--spring); }
.tpl-row.saved .price-mini { border-color: color-mix(in srgb, var(--ok) 34%, var(--line)); }
/* Kept but not priced yet: its box waits, in a dashed amber edge. */
.tpl-row.pending .price-mini { border-style: dashed; border-color: color-mix(in srgb, var(--warn) 55%, transparent); }
.tpl-row.pending .price-mini::placeholder { color: color-mix(in srgb, var(--warn) 80%, var(--text-2)); }
.gs-more { margin: 12px 4px 10px; }
.gs-more .chev { width: 16px; height: 16px; transition: transform .3s var(--ease-out); }
.gs-more.open .chev { transform: rotate(180deg); }
.gs-menu-add { margin-top: 12px; }

/* The team: a name and Add, then a portrait card per barber, its photo developing inside it. */
.gs-crew-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 10px; }
.gs-crew-row .gs-crew-add { height: 60px; padding-inline: 18px; }
.gs-crew-me { margin-top: 12px; }
.gs-crew-me .icon { width: 18px; height: 18px; color: var(--light); }
.gs-crew { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 18px; }
.gs-crew:empty { display: none; }
@media (min-width: 560px) { .gs-crew { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.gs-crew-card { position: relative; overflow: hidden; border-radius: 22px; background: var(--pane-edge), var(--surface); border: 1px solid var(--line-2); box-shadow: var(--depth-1); }
.photo-stage.compact { width: auto; margin: 0; padding: 0; }
.photo-stage.compact .portrait { border-radius: 0; box-shadow: none; }
.photo-stage.compact .portrait.empty { background: radial-gradient(80% 60% at 50% 30%, var(--light-wash), transparent 70%), var(--surface-2); }
.photo-stage.compact .portrait.empty .placeholder .icon { width: 44px; height: 44px; opacity: .35; }
.photo-stage.compact .studio-badge { bottom: 8px; padding: 4px 9px; font-size: 11px; }
.photo-stage.compact { position: relative; }
.gs-photo {
  position: absolute; z-index: 4; inset-inline: 10px; bottom: 10px; display: flex; align-items: center; justify-content: center; gap: 6px; height: 38px; border-radius: 99px;
  background: color-mix(in srgb, var(--bg-2) 70%, transparent); border: 1px solid var(--light-line); color: var(--text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 0 20px -8px var(--light-glow); transition: transform var(--t-release) var(--spring-soft);
}
.gs-photo:active { transform: scale(.95); transition-duration: var(--t-press); }
.gs-photo .icon { width: 17px; height: 17px; color: var(--light-hi); }
/* With a photo: a small round camera in the corner, out of the face's way. */
.gs-photo.has { inset-inline: auto 8px; top: 8px; bottom: auto; width: 36px; height: 36px; padding: 0; }
.gs-crew-info { display: flex; align-items: center; gap: 2px; padding-block: 6px; padding-inline: 12px 4px; }
.gs-crew-info b { flex: 1; min-width: 0; font-size: 14.5px; font-weight: 600; }
.gs-crew-info .icon-btn { width: 34px; height: 34px; border-radius: 10px; color: var(--text-2); }
.gs-crew-hint { margin-top: 16px; }

/* Hours: three plain answers over the week. The usual hours as lit 24-hour tracks (his own
   week lights "custom" by itself), the day off as chips, Friday after the prayer, then the
   week itself, where a day opens to be changed by hand. */
.gs-quick > .gs-h:first-child { margin-top: 0; }
.gs-usuals { display: grid; gap: 10px; }
.gs-usual {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px 12px; width: 100%; padding: 14px 16px;
  border-radius: 18px; color: var(--text); font: inherit; text-align: start; cursor: pointer;
  background: var(--pane-edge), var(--surface); border: 1.5px solid var(--line); box-shadow: var(--depth-1);
  transition: border-color .25s, box-shadow .3s, opacity .25s, transform var(--t-release) var(--spring-soft);
}
.gs-usual:active:not(:disabled) { transform: scale(.98); transition-duration: var(--t-press); transition-timing-function: var(--ease-press); }
.gs-usual:focus-visible { outline: 2px solid var(--light); outline-offset: 2px; }
.gs-usual-dot { position: relative; width: 20px; height: 20px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--line-2); transition: box-shadow .25s; }
.gs-usual-t { font-size: 15px; font-weight: 600; line-height: 1.4; }
.gs-usual-track { grid-column: 2; display: block; }
.gs-usual.on {
  border-color: var(--light); background: radial-gradient(90% 140% at 0% 0%, var(--light-wash), transparent 60%), var(--pane-edge), var(--surface);
  box-shadow: var(--depth-1), 0 0 0 1px var(--light-line), 0 0 28px -12px var(--light-glow);
}
[dir='rtl'] .gs-usual.on { background: radial-gradient(90% 140% at 100% 0%, var(--light-wash), transparent 60%), var(--pane-edge), var(--surface); }
.gs-usual.on .gs-usual-dot { box-shadow: inset 0 0 0 1.5px var(--light), 0 0 12px -2px var(--light-glow); }
.gs-usual.on .gs-usual-dot::after { content: ''; position: absolute; inset: 5px; border-radius: 50%; background: var(--light); box-shadow: 0 0 8px var(--light-glow); animation: pop .3s var(--spring); }
/* His own week: not something to pick, it lights by itself; quiet while unused. */
.gs-usual.custom { cursor: default; border-style: dashed; }
.gs-usual.custom.empty { opacity: .5; box-shadow: none; }
.gs-usual.custom.empty .gs-usual-track { display: none; }
/* A day as a 24-hour track: lit stretches, faint ticks at 6, 12 and 18. */
.mini-track { position: relative; display: block; height: 8px; border-radius: 99px; background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line); }
.mini-track .tick { position: absolute; top: -3px; bottom: -3px; inset-inline-start: var(--a); width: 1px; background: var(--line-2); }
.mini-track b { position: absolute; top: 0; bottom: 0; inset-inline-start: var(--a); width: calc(var(--b) - var(--a)); border-radius: 99px; background: linear-gradient(90deg, var(--neon-a), var(--neon-b)); box-shadow: 0 0 10px -1px var(--light-glow); }
.gs-usual:not(.on) .mini-track b { opacity: .55; box-shadow: none; }
.gs-dayoff { display: flex; flex-wrap: wrap; gap: 8px; }
.gs-off { position: relative; cursor: pointer; }
.gs-off input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.gs-off span {
  display: inline-grid; place-items: center; height: 40px; padding: 0 15px; border-radius: 99px; font-size: 14px; font-weight: 500; white-space: nowrap;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); transition: background-color .2s, border-color .2s, color .2s, box-shadow .25s, transform var(--t-release) var(--spring-soft);
}
.gs-off:active span { transform: scale(.94); transition-duration: var(--t-press); }
.gs-off input:checked + span { color: var(--text); border-color: var(--light); background: color-mix(in srgb, var(--light) 14%, var(--surface-2)); box-shadow: 0 0 0 1px var(--light-line), 0 0 18px -8px var(--light-glow); }
.gs-off input:focus-visible + span { outline: 2px solid var(--light); outline-offset: 2px; }
.gs-friday-card { margin-top: 18px; padding: 2px 16px; }
.gs-friday { transition: opacity .25s; }
.gs-friday.off { opacity: .45; }
.gs-week-cap { margin: 26px 2px 12px; }
.gs-week .week { padding-block: 4px; }

/* How customers book: three choices in rows; CliQ's details unfold under them as a lit pane. */
.gs-choices { display: grid; gap: 10px; }
.gs-choice.row { flex-direction: row; align-items: center; gap: 14px; padding: 16px; padding-inline-end: 50px; border-radius: 20px; text-align: start; }
.gs-choice.row .tile { width: 44px; height: 44px; border-radius: 14px; }
.gs-choice.row .tile .icon { width: 21px; height: 21px; }
.gs-choice.row.on::after { top: 50%; margin-top: -11px; inset-inline-end: 16px; }
.gs-choice-txt { display: grid; gap: 3px; min-width: 0; }
.gs-choice-txt b { font-size: 15.5px; font-weight: 600; }
.gs-choice-txt span { font-size: 13px; line-height: 1.5; color: var(--text-2); }
.gs-booking > .fold { border-radius: 22px; transition: grid-template-rows .4s var(--ease-out), opacity .3s, margin .4s var(--ease-out), padding .4s var(--ease-out); }
.gs-booking > .fold.open {
  margin-top: 12px; padding: 16px; background: radial-gradient(100% 60% at 50% 0%, var(--light-wash), transparent 70%), var(--pane-edge), var(--surface);
  box-shadow: inset 0 0 0 1px var(--light-line), var(--depth-1);
}
.gs-hint { display: flex; align-items: flex-start; gap: 8px; margin: 12px 4px 0; font-size: 13.5px; line-height: 1.55; color: var(--warn); }
.gs-hint .icon { flex: none; width: 16px; height: 16px; margin-top: 2px; }

/* The opening: his app on a phone in its own light, what is set up and what is missing, and
   «افتتح صالونك» in Next's place. Once open: the shop's pole lit beside the headline, the
   link to share, and "start your day". */
.gs-launch-head > .folio { margin-bottom: 14px; }
.gs-launch-head > .gs-title { padding-inline-end: 88px; }
/* A phone's narrow measure: a smaller berth (the numeral is a faint outline behind, its
   lower half may sit under the words), so a question does not leave one word alone. */
@media (max-width: 479px) { :is(.gs-step, .gs-launch-head) > .gs-title { padding-inline-end: 48px; } }
.gs-launch-phone {
  position: relative; isolation: isolate; display: grid; justify-items: center; margin-top: 22px; padding: 20px 0 14px; overflow: hidden; border-radius: 28px; border: 1px solid var(--line);
  background: radial-gradient(60% 50% at 50% 40%, color-mix(in srgb, var(--accent-lift) 16%, transparent), transparent 75%), var(--surface);
}
.gs-launch-phone > .gs-halo { inset: 8% 14% 20%; background: radial-gradient(closest-side, color-mix(in srgb, var(--accent-lift) 30%, transparent), transparent); opacity: .5; transition: opacity .8s; }
.gs-launch-phone.lit > .gs-halo { opacity: 1; }
:root[data-motion='full'] .gs-launch-phone.lit .phone-wrap { animation: float 6s ease-in-out infinite; }
.gs-checklist { display: grid; gap: 12px; margin-top: 22px; }
.gs-checklist h3 { padding: 14px 16px 4px; font-size: 13.5px; font-weight: 600; color: var(--text-2); }
.gs-checklist ul { margin: 0; padding: 0 0 4px; list-style: none; }
.gs-check { display: flex; align-items: center; gap: 12px; min-height: 50px; padding: 6px 16px; }
.gs-check + .gs-check { border-top: 1px solid var(--line); }
.gs-check .step-node { --sn: 28px; }
.gs-check .grow { min-width: 0; font-size: 14.5px; font-weight: 500; line-height: 1.4; }
.gs-check.later .grow { color: var(--text-2); }
.gs-check.later .step-node .icon { width: 50%; height: 50%; stroke-width: 2; }
.gs-st { flex: none; font-size: 12.5px; color: var(--text-3); }
.gs-check:has(.step-node[data-state='done']) .gs-st { color: var(--light); }
.gs-add-now { flex: none; padding: 4px 2px; font-size: 13.5px; }
.gs-missing { border-color: color-mix(in srgb, var(--warn) 34%, var(--line)); }
.gs-missing h3 { color: var(--warn); }
.gs-check.need .step-node { background: color-mix(in srgb, var(--warn) 16%, var(--surface-2)); color: var(--warn); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--warn) 55%, transparent); }
.gs-open-note { margin-top: 16px; }
/* Out of the way for a moment (the opening's ceremony). */
.gs-foot { transition: transform .45s var(--ease-out), opacity .3s; }
.gs-foot.away { transform: translateY(calc(100% + 30px)); opacity: 0; }
/* A step's own button in Next's place. */
.gs-foot-act { display: flex; flex: 1; min-width: 0; }
.gs-foot-act > .btn { flex: 1; min-width: 0; height: 54px; }
.gs-opened-head { display: flex; align-items: center; gap: 16px; }
.gs-opened-head .gs-sub { margin-top: 6px; }
.gs-open-sign { position: relative; flex: none; width: 72px; height: 72px; }
.gs-open-sign .ps-pole { scale: .6; margin-top: -36.5px; }
.gs-open-sign .ps-halo { inset: -16%; }
.gs-opened-t { font-size: 26px; font-weight: 700; line-height: 1.3; }
.gs-opened-t:focus { outline: none; }
.gs-launch.gs-opened .gs-launch-phone { margin-top: 20px; }
/* Open: the step's numeral steps back for the headline. */
.gs-num { transition: opacity .4s; }
.gs-body-in:has(.gs-launch.gs-opened) > .gs-num { opacity: 0; }
.gs-share { margin-top: 20px; padding: 16px; }
.gs-link {
  display: flex; align-items: center; justify-content: center; gap: 8px; height: 46px; padding: 0 16px; border-radius: 14px; font-size: 15px; font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--light-line); box-shadow: inset 0 1px 0 var(--rim-hi), 0 0 24px -12px var(--light-glow);
}
.gs-link .icon { flex: none; width: 15px; height: 15px; color: var(--ok); }
.gs-link span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.gs-share-acts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 10px; }
.gs-act {
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 4px 10px; border-radius: 16px; background: none; border: 0; color: var(--text);
  font: inherit; font-size: 13px; font-weight: 500; line-height: 1.35; text-align: center; cursor: pointer; transition: background-color .2s, transform var(--t-release) var(--spring-soft);
}
.gs-act:hover { background: var(--surface-2); }
.gs-act:active { transform: scale(.95); transition-duration: var(--t-press); }
.gs-act .tile { width: 48px; height: 48px; border-radius: 50%; }
.gs-act .tile .icon { width: 21px; height: 21px; }
.gs-next-steps .gs-h { color: var(--text-2); }
.gs-next-steps ul { margin: 0; padding: 0; list-style: none; }
.gs-next-steps li + li { border-top: 1px solid var(--line); }
.gs-later { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 60px; padding: 8px 16px; background: none; border: 0; color: var(--text); font: inherit; font-weight: 500; text-align: start; cursor: pointer; transition: background-color .2s; }
.gs-later:hover { background: var(--surface-2); }
.gs-later .tile { width: 38px; height: 38px; border-radius: 12px; }
.gs-later .tile .icon { width: 18px; height: 18px; }
/* The ribbon cut on the salon's phone (a public-themed subtree: the salon's own light). */
.gs-cut { position: absolute; inset: 0; z-index: 6; pointer-events: none; --ky: 52%; }
.gs-cut .bx-stage { --shw: 110px; }

/* Where he is, step by step: the map sheet on a phone, the rail on a wide screen. */
.gs-node { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px 10px; border: 0; border-radius: 14px; background: none; color: var(--text-2); text-align: start; cursor: pointer; transition: background-color .2s, color .2s; }
.gs-node:hover { background: var(--surface); }
.gs-node .step-node { --sn: 30px; transition: background-color .3s, box-shadow .3s; }
.gs-node-txt { display: grid; min-width: 0; line-height: 1.35; }
.gs-node .lbl { font-size: 14.5px; font-weight: 500; }
.gs-node .st { font-size: 11.5px; color: var(--text-3); }
.gs-node[data-state='now'] { color: var(--text); background: color-mix(in srgb, var(--light) 9%, transparent); box-shadow: inset 0 0 0 1px var(--light-line); }
.gs-node[data-state='now'] .lbl { font-weight: 600; }
.gs-node[data-state='done'] .st { color: var(--light); }
.gs-node[data-state='done'] { color: var(--text); }
.gs-map { display: grid; gap: 4px; margin: 0; padding: 0; list-style: none; }
.gs-map-line { margin: 0 4px 12px; font-size: 13px; color: var(--text-2); }
.gs-map-body .gs-exit { margin-top: 14px; }
.gs-rail { display: none; }

/* The live phone: what it shows, said under it; a light scans it once when that changes. */
.pv-caption { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 26px; font-size: 13px; color: var(--text-2); text-align: center; }
.pv-caption::before { content: ''; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--light); box-shadow: 0 0 10px var(--light-glow); }
.pv-phone > .phone-wrap, .pv-scan-band { grid-area: 1 / 1; }
/* Over the phone's glass only (inside its 11px bezel). */
.pv-scan-band { position: relative; z-index: 2; align-self: start; width: calc(278px * var(--scale, 1)); height: calc(608px * var(--scale, 1)); margin-top: calc(11px * var(--scale, 1)); border-radius: calc(40px * var(--scale, 1)); overflow: hidden; pointer-events: none; }
.pv-scan-band::before {
  content: ''; position: absolute; inset-inline: 0; top: 0; height: 26%; opacity: 0; translate: 0 -100%;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--neon-a) 16%, transparent) 70%, color-mix(in srgb, var(--neon-a) 55%, #fff) 97%, transparent);
}
.pv-phone.pv-scan .pv-scan-band::before { animation: pv-scan .65s var(--ease-sweep) both; }
@keyframes pv-scan { 0% { opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { opacity: 0; translate: 0 390%; } }
/* The part being edited is spotlit; the rest of the app steps back. */
.mini [data-region] { border-radius: 12px; transition: opacity .3s, box-shadow .3s; }
.mini .st[data-region] { border-radius: 99px; }
.mini[data-focus] .mini-actions[data-region] { border-radius: 99px; margin-inline: auto; width: max-content; }
.mini[data-focus] [data-region]:not(.on) { opacity: .4; }
/* The booking bar floats over the page: dimmed, it stays solid (see-through, the team
   would show through it). */
.mini[data-focus] .mini-cta[data-region]:not(.on) { opacity: 1; filter: brightness(.45) saturate(.5); }
/* The spotlight's ring stands a little off the part it lights, clear of its heading. */
.mini[data-focus] [data-region].on { outline: 1.5px solid var(--accent-lift); outline-offset: 4px; box-shadow: 0 0 24px -4px var(--accent-lift); }
.mini.day[data-focus] [data-region].on { outline-color: var(--accent-ink); box-shadow: 0 0 18px -6px var(--accent-ink); }
.mini[data-focus='team'] :is(.mini-hero, .mini-body) { translate: 0 -110px; }
/* Scrolled up to the team, the hero would peek out under the phone's island: it steps away. */
.mini[data-focus='team'] .mini-hero { opacity: 0; transition: opacity .3s; }
.mini-team-wrap { margin-top: 14px; }
/* The deposit a customer is asked for, just over the booking button. */
.mini-dep { position: absolute; z-index: 3; left: 50%; bottom: 68px; translate: -50% 0; display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 99px; font-size: 10px; font-weight: 600; white-space: nowrap; color: #f7f4ef; background: color-mix(in srgb, var(--night), #fff 12%); border: 1px solid color-mix(in srgb, var(--accent-lift) 40%, transparent); }
.mini-dep .icon { width: 11px; height: 11px; color: var(--accent-lift); }
.mini.day .mini-dep { color: #1b1a19; background: #fff; border-color: color-mix(in srgb, var(--accent-ink) 30%, transparent); }
.mini.day .mini-dep .icon { color: var(--accent-ink); }

@media (min-width: 1080px) {
  .studio.focus { grid-template-columns: minmax(0, 1fr) 440px; }
  .studio.focus .s-page { max-width: none; margin: 0; padding: 0; }
  .studio.focus .s-preview .pv-phone { margin-top: 4px; }
  .gs { display: grid; grid-template-columns: 300px minmax(0, 1fr); min-height: 100dvh; }
  .gs-top { display: none; }
  .gs-rail {
    position: sticky; top: 0; display: flex; flex-direction: column; height: 100dvh; overflow-y: auto; padding: 30px 16px 20px; scrollbar-width: none;
    border-inline-end: 1px solid var(--line); background: linear-gradient(180deg, color-mix(in srgb, var(--light) 5%, transparent), transparent 40%), color-mix(in srgb, var(--bg) 70%, transparent);
  }
  .gs-rail-head { padding: 0 6px 22px; margin-bottom: 14px; border-bottom: 1px solid var(--line); text-align: center; }
  .gs-rail-name { margin-top: 14px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 16px; font-weight: 700; }
  .gs-rail-line { margin-top: 2px; font-size: 12.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
  .gs-nodes { margin: 0; padding: 0; list-style: none; }
  /* Between two steps, a short tube; the pole's light runs down it as far as the step he is on. */
  .gs-conn { position: relative; display: block; width: 4px; height: 14px; margin: -3px 0; margin-inline-start: 23px; overflow: hidden; overflow: clip; border-radius: 2px; background: var(--surface-3); }
  .gs-conn .pole-stripes { transform: scaleY(0); transform-origin: top; transition: transform .5s var(--ease-out); box-shadow: 0 0 8px var(--light-glow); }
  .gs-nodes li.lit .gs-conn .pole-stripes { transform: none; }
  /* Not lit yet: its stripes are out of sight, so they stand still. */
  .gs-nodes li:not(.lit) .gs-conn .pole-stripes { animation: none; }
  .gs-rail-foot { display: grid; justify-items: start; gap: 12px; margin-top: auto; padding: 18px 8px 0; }
  .gs-rail-links { display: flex; flex-wrap: wrap; gap: 4px 16px; }
  .gs-body { padding: 52px 56px 24px; }
  .gs-body-in { display: flex; flex-direction: column; max-width: 640px; min-height: calc(100dvh - 76px); margin: 0 auto; }
  .gs-stage-box { flex: 1; }
  .gs-num { top: -18px; font-size: 128px; }
  .gs-step > :is(.gs-title, .gs-sub) { max-width: none; padding-inline-end: 150px; }
  .gs-title { font-size: 30px; }
  .gs-welcome .gs-title { font-size: 34px; }
  .gs-foot {
    position: sticky; inset-inline: auto; bottom: 24px; margin-top: 36px; padding: 8px; border: 1px solid var(--line-2); border-radius: 24px;
    background: var(--pane-edge), color-mix(in srgb, var(--bg-2) 92%, transparent); box-shadow: inset 0 1px 0 rgb(255 255 255 / .08), var(--depth-3);
  }
  .gs-foot-in { max-width: none; }
  /* Under the bar to the screen's edge, what scrolls by is veiled, so nothing peeks out beneath it. */
  .gs-foot::after { content: ''; position: absolute; inset-inline: -40px; top: calc(100% + 1px); height: 26px; background: var(--bg); pointer-events: none; }
  .gs-back { width: 48px; height: 48px; }
  .gs-next { flex: none; width: 280px; height: 48px; margin-inline-start: auto; }
  .gs-skip { position: static; translate: none; margin-inline-start: auto; background: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .gs-skip:not([hidden]) + .gs-back + .gs-next { margin-inline-start: 0; }
  /* The welcome has nowhere to go back to: its one button stands in the middle. */
  .gs[data-step='welcome'] .gs-foot-in { justify-content: center; }
  .gs[data-step='welcome'] .gs-next { margin-inline-start: 0; }
  .gs-stage { display: none; }
  .gs-look .scroller.palettes, .s-page .gs-look .scroller.palettes { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  /* The opening plays on the live phone beside the guide. */
  .gs-launch-phone { display: none; }
  .gs-launch-head > :is(.gs-title, .gs-sub) { max-width: none; padding-inline-end: 150px; }
  .gs-foot-act { flex: none; width: 280px; margin-inline-start: auto; }
  .gs-foot-act > .btn { height: 48px; }
  .gs-opened-t { font-size: 32px; }
  .gs-open-sign { width: 92px; height: 92px; }
  .gs-open-sign .ps-pole { scale: .8; margin-top: -35.8px; }
  .gs-cut .bx-stage { --shw: 150px; }
  .gs-crew { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Confirmations rise over the question's column, above its foot. */
  [data-theme='studio'] body:has(.gs-foot):not(:has(> .sheet-backdrop)) > .toast { bottom: 108px; left: calc(50% - 70px); }
  [data-theme='studio'][dir='rtl'] body:has(.gs-foot):not(:has(> .sheet-backdrop)) > .toast { left: calc(50% + 70px); }
}
@media (min-width: 1080px) and (max-width: 1279px) {
  .studio.focus { grid-template-columns: minmax(0, 1fr) 340px; }
  .gs { grid-template-columns: 248px minmax(0, 1fr); }
  .gs-body { padding: 40px 32px 24px; }
  .gs-next { width: 240px; }
}

/* ==========================================================================
   Brand studio
   ========================================================================== */
.stage { position: relative; border-radius: var(--r-xl); overflow: hidden; border: 1px solid var(--line); background:
  radial-gradient(60% 50% at 30% 25%, color-mix(in srgb, var(--glow-1) 26%, transparent), transparent 75%), radial-gradient(60% 50% at 75% 75%, color-mix(in srgb, var(--glow-3) 20%, transparent), transparent 75%), var(--surface); }
.stage-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.stage-track::-webkit-scrollbar { display: none; }
.stage-slide { flex: none; width: 100%; scroll-snap-align: center; display: flex; flex-direction: column; align-items: center; padding: 24px 0 12px; }
.stage-slide .caption { font-size: 13px; color: var(--text-2); margin-top: 12px; }
.stage-dots { display: flex; justify-content: center; gap: 6px; padding-bottom: 14px; }
.stage-dots button { width: 7px; height: 7px; padding: 0; border-radius: 99px; border: 0; background: var(--line-2); cursor: pointer; transition: width .3s var(--ease-out), background-color .3s; }
.stage-dots button.on { width: 22px; background: var(--grad, var(--brand)); }

.palette { display: flex; flex-direction: column; gap: 8px; width: 104px; padding: 8px 8px 10px; border-radius: 18px; background: var(--surface-2); border: 1px solid var(--line); cursor: pointer; text-align: start; transition: border-color .2s, transform .25s var(--spring), background-color .2s; }
.palette:active { transform: scale(.95); }
.palette.on { border-color: var(--brand); background: var(--surface-3); box-shadow: 0 0 0 3px var(--brand-soft); }
.palette:focus-visible { outline-offset: 3px; }
/* Each palette as its page in miniature: the main colour's night, lit by the accent,
   with the accent's booking button along the bottom. */
.palette .sw {
  height: 64px; border-radius: 12px; position: relative; overflow: hidden;
  background: radial-gradient(90% 80% at 85% 0%, color-mix(in srgb, var(--a) 60%, transparent), transparent 70%), linear-gradient(160deg, color-mix(in srgb, var(--p), #fff 14%), var(--p));
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .1);
}
.palette .sw::before { content: ''; position: absolute; inset-inline: 10px 34px; top: 12px; height: 6px; border-radius: 99px; background: color-mix(in srgb, var(--a) 35%, rgb(255 255 255 / .3)); }
.palette .sw::after { content: ''; position: absolute; inset-inline: 10px; bottom: 10px; height: 9px; border-radius: 99px; background: var(--a); box-shadow: 0 4px 12px -3px var(--a); }
.palette .nm { font-size: 12.5px; font-weight: 500; color: var(--text-2); padding: 0 2px; }
.palette.on .nm { color: var(--text); }

.color-row { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--line); cursor: pointer; }
.color-row + .color-row { margin-top: 10px; }
.color-row .sw { position: relative; width: 40px; height: 40px; border-radius: 12px; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .15); overflow: hidden; flex: none; }
.color-row input[type='color'] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
.color-row .hex { font-size: 13px; color: var(--text-3); direction: ltr; }

.logo-drop { display: flex; align-items: center; gap: 16px; }
.logo-drop .app-icon { --s: 84px; cursor: pointer; }
.logo-drop .app-icon.empty-logo { background: var(--surface-2); border: 1.5px dashed var(--line-2); color: var(--text-3); box-shadow: none; }

.style-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.style-card { position: relative; cursor: pointer; text-align: center; }
.style-card input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.style-card .portrait { border-radius: 16px; border: 2px solid transparent; transition: border-color .2s, transform .3s var(--spring), box-shadow .2s; }
.style-card .nm { display: block; font-size: 12.5px; color: var(--text-2); margin-top: 6px; }
.style-card input:checked ~ .portrait { border-color: var(--brand); box-shadow: 0 10px 30px -12px var(--brand-glow); transform: translateY(-2px); }
.style-card input:checked ~ .nm { color: var(--text); font-weight: 600; }
.style-card input:focus-visible ~ .portrait { outline: 2px solid var(--light); outline-offset: 2px; }
.style-card .tint { position: absolute; inset: 0; mix-blend-mode: color; opacity: .55; }

/* ==========================================================================
   Services
   ========================================================================== */
.quick { padding: 22px 18px; }
.quick h2 { font-size: 20px; }
.quick p { color: var(--text-2); font-size: 14px; margin-top: 4px; }
.type-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 18px; }
.type-card { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 18px 8px 14px; border-radius: 20px; background: var(--surface-2); border: 1px solid var(--line); cursor: pointer; text-align: center; transition: transform .25s var(--spring), border-color .2s, background-color .2s; }
.type-card:hover { border-color: var(--brand-line); background: var(--surface-3); }
.type-card:active { transform: scale(.95); }
.type-card .type-ic { width: 56px; height: 56px; border-radius: 18px; }
.type-card .type-ic .icon { width: 28px; height: 28px; }
.type-card .nm { font-size: 13.5px; font-weight: 600; line-height: 1.3; }

.svc { display: flex; align-items: center; gap: 14px; width: 100%; padding: 14px 16px; background: none; border: 0; text-align: start; cursor: pointer; transition: background-color .2s; }
.svc:hover { background: var(--surface-2); }
.svc .name { font-weight: 600; font-size: 15.5px; }
.svc .meta { display: flex; align-items: center; gap: 8px; margin-top: 4px; color: var(--text-2); font-size: 13px; }
.svc .price { text-align: end; font-weight: 700; font-size: 16px; white-space: nowrap; }
.svc .price small { display: block; font-size: 11px; font-weight: 400; color: var(--text-3); }
.svc.off { opacity: .5; }
.svc-row { display: flex; align-items: center; }
.svc-row .reorder { display: flex; gap: 4px; padding-inline-end: 12px; }
.svc-row .reorder .icon-btn { width: 36px; height: 36px; border-radius: 11px; }

.icon-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(48px, 1fr)); gap: 8px; }
.icon-opt { display: grid; place-items: center; aspect-ratio: 1; min-height: 44px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); cursor: pointer; transition: background-color .2s, border-color .2s, color .2s; }
.icon-opt .icon { width: 24px; height: 24px; }
@media (hover: hover) { .icon-opt:hover { border-color: var(--brand-line); color: var(--text); } }
.icon-opt.on { background: var(--brand-soft); border-color: var(--brand); color: var(--violet, var(--brand)); }
.icon-opt:focus-visible { outline: 2px solid var(--light); outline-offset: 2px; }
.icon-hint { margin-top: 10px; }

.price-field { display: flex; align-items: baseline; justify-content: center; gap: 8px; padding: 14px; border-radius: var(--r-lg); background: var(--surface-2); border: 1px solid var(--line); transition: border-color .2s, box-shadow .2s; }
.price-field:focus-within { border-color: var(--brand-line); box-shadow: 0 0 0 4px var(--brand-soft); }
/* The price and its currency sit together, however long the price is. */
.price-field { cursor: text; }
.price-field input { width: auto; field-sizing: content; min-width: 1.4em; max-width: 100%; background: none; border: 0; outline: none; font-size: 40px; font-weight: 700; text-align: center; direction: ltr; color: var(--text); padding: 0; }
/* Without field-sizing the input would take its default (very wide) size: give it room
   for a JD price; the service editor's priceInput still sets the width as one types. */
@supports not (field-sizing: content) { .price-field input { width: 5.5ch; } }
.price-field input::placeholder { color: var(--text-3); }
.price-field .cur { font-size: 18px; color: var(--text-2); font-weight: 500; }
.price-field.invalid { border-color: var(--danger); }
.field-label { display: block; font-size: 14px; font-weight: 500; color: var(--text-2); margin: 20px 2px 10px; }
.field-label:first-child { margin-top: 0; }

.stepper { display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); }
.stepper .icon-btn { width: 34px; height: 34px; border-radius: 10px; background: var(--surface-3); border: 0; }
.stepper .v { min-width: 64px; text-align: center; font-weight: 600; font-size: 15px; }

.tpl-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; }
.tpl-row + .tpl-row { border-top: 1px solid var(--line); }
.tpl-row .check { position: relative; flex: none; }
.tpl-row .check input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.tpl-row .check span { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; border: 1.5px solid var(--line-2); color: transparent; transition: background-color .2s, border-color .2s, color .2s; cursor: pointer; }
.tpl-row .check input:checked + span { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.tpl-row .check .icon { width: 16px; height: 16px; stroke-width: 3; }
.tpl-row .tile { width: 40px; height: 40px; border-radius: 12px; }
/* A small price box with its currency inside, at the end. */
.price-mini-wrap { position: relative; flex: none; display: block; width: 104px; }
.tpl-row .price-mini { width: 100%; height: 44px; padding-inline: 10px 38px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--line); text-align: start; font-weight: 600; font-size: 15px; color: var(--text); outline: none; font-variant-numeric: tabular-nums; }
[dir='rtl'] .tpl-row .price-mini { padding-inline: 38px 10px; direction: ltr; text-align: right; }
.price-mini-wrap .cur { position: absolute; top: 50%; inset-inline-end: 10px; transform: translateY(-50%); font-size: 12px; color: var(--text-3); pointer-events: none; }
.tpl-row .price-mini::placeholder { color: var(--text-3); font-weight: 400; font-size: 13px; }
.tpl-row .price-mini:focus { border-color: var(--brand-line); box-shadow: 0 0 0 3px var(--brand-soft); }
.tpl-row .price-mini.invalid { border-color: var(--danger); }
.tpl-row.off .tile, .tpl-row.off .grow { opacity: .45; }

/* ==========================================================================
   Team
   ========================================================================== */
.team-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 560px) { .team-grid { grid-template-columns: repeat(3, 1fr); } }
.member { position: relative; display: block; width: 100%; padding: 0; border: 0; background: none; text-align: start; cursor: pointer; border-radius: var(--r-lg); transition: transform .3s var(--spring); }
.member:active { transform: scale(.97); }
.member .portrait { border: 1px solid var(--line); }
.member .portrait::after { content: ''; position: absolute; inset: 45% 0 0; background: linear-gradient(transparent, rgb(0 0 0 / .78)); }
.member .info { position: absolute; z-index: 1; inset-inline: 12px; bottom: 12px; color: #fff; }
.member .info .name { font-weight: 700; font-size: 16px; line-height: 1.25; }
.member .info .role { font-size: 12.5px; opacity: .75; }
.member .flag { position: absolute; z-index: 1; top: 10px; inset-inline-start: 10px; }
.member .flag .pill { background: rgb(0 0 0 / .55); color: #fff; border-color: rgb(255 255 255 / .15); backdrop-filter: blur(8px); }
.member.paused .portrait > img { filter: grayscale(1) brightness(.6); }
.add-member { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; aspect-ratio: 4 / 5; width: 100%; border-radius: var(--r-lg); border: 1.5px dashed var(--line-2); background: color-mix(in srgb, var(--surface) 60%, transparent); color: var(--text-2); cursor: pointer; transition: border-color .2s, color .2s, transform .3s var(--spring); }
.add-member:hover { border-color: var(--brand-line); color: var(--text); }
.add-member:active { transform: scale(.97); }
.add-member .tile { width: 52px; height: 52px; border-radius: 50%; }
.add-member span { font-weight: 500; font-size: 14.5px; }
/* Team editor: Arabic name and title side by side; English folds away. */
.team-names { margin-top: 18px; align-items: start; }
.en-toggle { margin-top: 8px; }
.fold > .en-fields { padding: 10px 4px 4px; margin: 0 -4px -4px; }
.en-fields > .f + .f { margin-top: 12px; }
/* An example ("e.g. Senior barber") goes once the field has a value. */
.f.example:has(> input:not(:placeholder-shown)) > .hint { display: none; }

/* Room above for the halo and the rounded top, clear of the sheet's head. */
.photo-stage { width: min(250px, 72%); margin: 0 auto; padding-block: 18px 6px; }
.photo-stage .portrait { border-radius: 26px; box-shadow: 0 30px 60px -30px rgb(0 0 0 / .9), 0 0 0 1px var(--line-2); }
.photo-actions { display: flex; justify-content: center; gap: 8px; margin-top: 14px; }
.drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; text-align: center; padding: 20px;
  aspect-ratio: 4 / 5; border-radius: 26px; border: 1.5px dashed var(--line-2); background: var(--surface); color: var(--text-2); cursor: pointer;
  transition: border-color .2s, background-color .2s;
}
.drop:hover, .drop.over { border-color: var(--brand); background: var(--brand-soft); }
.drop .tile { width: 58px; height: 58px; border-radius: 50%; }
.drop b { color: var(--text); font-weight: 600; }
.drop small { font-size: 12.5px; color: var(--text-3); }

.studio-badge { position: absolute; z-index: 2; bottom: 10px; left: 50%; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; padding: 5px 11px; border-radius: 99px; font-size: 12px; font-weight: 600; color: var(--on-brand); background: var(--grad, var(--brand)); box-shadow: 0 8px 20px -6px var(--brand-glow); pointer-events: none; }
.studio-badge .icon { width: 14px; height: 14px; }

/* processing */
.processing { position: absolute; inset: 0; z-index: 3; overflow: hidden; display: grid; place-items: center; background: rgb(9 9 11 / .55); backdrop-filter: blur(3px); color: #fff; }
.processing::before { content: ''; position: absolute; inset-inline: 0; height: 40%; top: -40%; background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--brand) 55%, transparent), transparent); animation: scan 1.6s var(--ease-out) infinite; }
.processing .msg { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; text-align: center; padding: 0 12px; }
.processing .icon { width: 28px; height: 28px; color: var(--brand); animation: twinkle 1.2s ease-in-out infinite; }
@keyframes scan { to { top: 100%; } }
@keyframes twinkle { 50% { transform: scale(1.2) rotate(12deg); opacity: .7; } }
/* The studio touch arrives: the finished portrait comes into focus. (Not .reveal,
   which is the salon page's scroll-in.) */
.photo-reveal { animation: photo-reveal .9s var(--ease-out); }
@keyframes photo-reveal { from { filter: blur(14px) brightness(1.4); transform: scale(1.04); } }

/* ==========================================================================
   Hours
   ========================================================================== */
.week { padding: 6px 0; }
.day-row { padding: 12px 16px; cursor: pointer; transition: background-color .2s; }
.day-row + .day-row { border-top: 1px solid var(--line); }
.day-row:hover { background: color-mix(in srgb, var(--surface-2) 60%, transparent); }
.day-row.open-editor { background: var(--surface-2); cursor: default; }
.day-row { position: relative; }
/* The error edge on the row's start side (the right in Arabic). */
.day-row.invalid::before { content: ''; position: absolute; inset-block: 0; inset-inline-start: 0; width: 3px; background: var(--danger); }
.day-row.invalid { background: color-mix(in srgb, var(--danger) 7%, var(--surface-2)); }
.day-line:focus-visible { outline-offset: 6px; border-radius: 8px; }
.day-line { display: flex; align-items: center; gap: 14px; }
.day-line .info { width: 132px; flex: none; }
.day-line .dname { font-weight: 600; font-size: 14.5px; line-height: 1.3; }
.day-line .dname.today::after { content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); margin-inline-start: 6px; vertical-align: middle; box-shadow: 0 0 8px var(--brand-glow); }
.day-line .summary { font-size: 12px; color: var(--text-2); line-height: 1.4; margin-top: 2px; white-space: nowrap; }
.day-line .summary.closed { color: var(--text-3); }
.scale-line { display: flex; gap: 14px; padding: 12px 16px 0; font-size: 11px; color: var(--text-3); }
.scale-line .info { width: 132px; flex: none; }
.scale-line .marks { position: relative; flex: 1; height: 14px; }
.scale-line .marks span { position: absolute; top: 0; white-space: nowrap; }
.scale-line .marks span:nth-child(1) { inset-inline-start: 0; }
.scale-line .marks span:nth-child(2) { inset-inline-start: 50%; transform: translateX(50%); }
[dir='ltr'] .scale-line .marks span:nth-child(2) { transform: translateX(-50%); }
.scale-line .marks span:nth-child(3) { inset-inline-end: 0; }
.track { position: relative; flex: 1; height: 10px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.track .seg { position: absolute; top: 0; bottom: 0; border-radius: 99px; background: var(--grad, var(--brand)); box-shadow: 0 0 14px -2px var(--brand-glow); }
.week.intro .seg { animation: grow .9s var(--ease-out) both; animation-delay: calc(var(--row, 0) * 70ms + 150ms); }
[dir='rtl'] .track .seg { transform-origin: right center; }
[dir='ltr'] .track .seg { transform-origin: left center; }
@keyframes grow { from { transform: scaleX(0); opacity: 0; } }
.track .now { position: absolute; top: -3px; bottom: -3px; width: 2px; border-radius: 2px; background: var(--text); }
.day-editor { margin-top: 14px; animation: rise .35s var(--ease-out); }
.range { display: flex; align-items: center; gap: 8px; }
.range + .range { margin-top: 8px; }
.range .to { color: var(--text-3); font-size: 13px; }
.time-pill { position: relative; flex: 1; }
.time-pill select { width: 100%; height: 48px; padding: 0 14px; border-radius: 14px; background: var(--surface-3); border: 1px solid var(--line-2); color: var(--text); font-size: 15px; font-weight: 500; appearance: none; cursor: pointer; text-align: center; text-align-last: center; outline: none; font-variant-numeric: tabular-nums; }
.time-pill select:focus { border-color: var(--brand-line); box-shadow: 0 0 0 3px var(--brand-soft); }
.time-pill .next { position: absolute; inset-inline: 0; bottom: -17px; text-align: center; font-size: 10.5px; color: var(--brand); }
.range.has-next { margin-bottom: 14px; }
.day-tools { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

/* ==========================================================================
   App icon, phone preview, mini app, home screen
   ========================================================================== */
.app-icon {
  --s: 60px; position: relative; display: grid; place-items: center; flex: none; width: var(--s); height: var(--s);
  border-radius: 23%; overflow: hidden; color: var(--on-primary);
  background: linear-gradient(150deg, color-mix(in srgb, var(--primary) 78%, #fff) 0%, var(--primary) 55%, color-mix(in srgb, var(--primary) 85%, #000) 100%);
  box-shadow: 0 1px 0 rgb(255 255 255 / .2) inset, 0 0 0 1px rgb(255 255 255 / .08), 0 8px 20px -8px rgb(0 0 0 / .6);
}
.app-icon.logo { background: #fff; }
.app-icon.studio-mark { background: var(--grad); color: #fff; }
.app-icon.studio-mark .icon { width: 55%; height: 55%; }
.app-icon.logo img { width: 84%; height: 84%; object-fit: contain; }
.app-icon svg { width: 62%; height: 62%; }

.phone-wrap { position: relative; width: calc(300px * var(--scale, 1)); height: calc(630px * var(--scale, 1)); flex: none; }
.phone {
  position: absolute; top: 0; left: 50%; width: 300px; height: 630px; padding: 11px; border-radius: 50px;
  transform: translateX(-50%) scale(var(--scale, 1)); transform-origin: top center;
  background: linear-gradient(150deg, #34343c, #101014 45%, #1c1c22);
  box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / .14), 0 50px 90px -40px rgb(0 0 0 / .95), 0 0 80px -30px var(--brand-glow);
}
.phone-screen { position: relative; width: 100%; height: 100%; border-radius: 40px; overflow: hidden; background: #f6f5f2; direction: inherit; }
.phone-island { position: absolute; z-index: 5; top: 11px; left: 50%; width: 92px; height: 27px; margin-left: -46px; border-radius: 20px; background: #000; }
.phone-status { position: absolute; z-index: 4; top: 0; inset-inline: 0; height: 48px; display: flex; align-items: center; justify-content: space-between; padding: 4px 26px 0; color: #fff; font-size: 13px; font-weight: 600; direction: ltr; }
.phone-status .bars { display: flex; gap: 4px; align-items: center; }
.phone-status .bars i { display: block; width: 16px; height: 10px; border-radius: 3px; border: 1.5px solid currentColor; opacity: .9; }
.phone-status .bars b { display: block; width: 14px; height: 9px; border-radius: 2px; background: currentColor; opacity: .9; }

/* The salon's night page in miniature, as the owner's live preview. */
.mini { position: absolute; inset: 0; display: flex; flex-direction: column; font-family: var(--font); color: #f7f4ef; text-align: start; background: var(--night); }
.mini-hero { position: relative; isolation: isolate; flex: none; padding: 56px 18px 18px; text-align: center; overflow: hidden;
  background: radial-gradient(70% 60% at 15% 10%, color-mix(in srgb, var(--primary), #fff 18%), transparent 70%), radial-gradient(60% 55% at 95% 25%, color-mix(in srgb, var(--accent-lift) 55%, transparent), transparent 70%), var(--night); }
.mini-hero::after { content: ''; position: absolute; inset: auto 0 0; height: 45%; z-index: -1; background: linear-gradient(transparent, var(--night)); }
.mini-mirror { position: relative; width: 84px; height: 84px; margin: 0 auto 10px; display: grid; place-items: center; }
/* The same ring of 18 round mirror bulbs as the salon's page and launch screen (bulbRing). */
.mini-lights { --ml: var(--accent-lift); position: absolute; inset: 0; pointer-events: none; }
.mini-lights i { position: absolute; left: 50%; top: 50%; width: 4px; height: 4px; margin: -2px; border-radius: 50%; background: var(--ml); box-shadow: 0 0 6px 1px color-mix(in srgb, var(--ml) 60%, transparent); transform: rotate(calc(var(--i) * 360deg / var(--n, 18))) translateY(calc(var(--ring, 39px) * -1)); animation: mirror-light 2.8s ease-in-out infinite; animation-delay: calc(var(--i) * -.155s); }
.mini.day .mini-hero:not(.has-cover) .mini-lights, .mini-splash.day .mini-lights { --ml: var(--accent); }
/* The hero's round buttons (call, WhatsApp, map, share). */
.mini-actions { display: flex; justify-content: center; gap: 10px; margin-top: 10px; }
.mini-actions span { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: rgb(255 255 255 / .08); border: 1px solid rgb(255 255 255 / .14); }
.mini-actions .icon { width: 13px; height: 13px; }
.mini.day .mini-hero:not(.has-cover) .mini-actions span { background: color-mix(in srgb, var(--on-primary) 12%, transparent); border-color: color-mix(in srgb, var(--on-primary) 20%, transparent); }
.mini-hero .app-icon { --s: 58px; border-radius: 18px; box-shadow: 0 0 0 1px rgb(255 255 255 / .2), 0 12px 26px -8px rgb(0 0 0 / .7), 0 0 30px -6px color-mix(in srgb, var(--accent-lift) 60%, transparent); }
.mini-hero .t { font-size: 19px; font-weight: 700; line-height: 1.25; }
.mini-hero .a { font-size: 11px; opacity: .72; margin-top: 4px; }
.mini-hero .st { display: inline-flex; align-items: center; gap: 5px; margin-top: 10px; padding: 3px 10px; border-radius: 99px; font-size: 10.5px; background: rgb(255 255 255 / .08); border: 1px solid rgb(255 255 255 / .12); }
.mini-hero .st::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 6px #4ade80; }
.mini-hero .st.closed::before { background: #9aa0a6; box-shadow: none; }
.mini-body { flex: 1; overflow: hidden; padding: 10px 14px 80px; }
.mini-h { font-size: 12.5px; font-weight: 700; margin: 2px 2px 8px; }
.mini-svc { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 14px; background: color-mix(in srgb, var(--night), #fff 8%); border: 1px solid rgb(255 255 255 / .08); }
.mini-svc + .mini-svc { margin-top: 6px; }
.mini-svc .e { flex: none; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; color: var(--accent-lift); background: color-mix(in srgb, var(--accent-lift) 20%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-lift) 30%, transparent); }
.mini-svc .e .icon { width: 17px; height: 17px; }
.mini-svc .n { font-size: 12px; font-weight: 600; line-height: 1.3; }
.mini-svc .d { font-size: 10px; color: rgb(247 244 239 / .55); }
.mini-svc .p { margin-inline-start: auto; font-size: 12px; font-weight: 700; white-space: nowrap; color: var(--accent-lift); }
.mini-team { display: flex; gap: 8px; }
.mini-team > div { position: relative; width: 74px; border-radius: 12px; overflow: hidden; }
.mini-team img, .mini-team .ph { display: grid; place-items: center; width: 74px; height: 92px; object-fit: cover; background: color-mix(in srgb, var(--night), #fff 12%); color: rgb(247 244 239 / .5); }
.mini-team .nm { position: absolute; inset: auto 0 0; padding: 14px 6px 5px; font-size: 10px; font-weight: 600; color: #fff; background: linear-gradient(transparent, rgb(0 0 0 / .75)); }
.mini-cta { position: absolute; z-index: 3; inset-inline: 14px; bottom: 16px; height: 44px; border-radius: 14px; display: grid; place-items: center; font-size: 13px; font-weight: 700; color: var(--on-accent-lift);
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent-lift), #fff 24%), var(--accent-lift) 48%, color-mix(in srgb, var(--accent-lift), #000 16%)); box-shadow: 0 10px 26px -8px color-mix(in srgb, var(--accent-lift) 75%, transparent), inset 0 1px 0 rgb(255 255 255 / .3); }
.mini-empty { font-size: 11px; color: rgb(247 244 239 / .5); padding: 10px 2px; }
/* The salon's cover photo behind the mini hero, under a scrim. */
.mini-hero .cover { position: absolute; inset: 0; z-index: -3; width: 100%; height: 100%; object-fit: cover; }
.mini-hero.has-cover { color: #fff; }
.mini-hero.has-cover::before { content: ''; position: absolute; inset: 0; z-index: -2; background: linear-gradient(180deg, rgb(0 0 0 / .45), rgb(0 0 0 / .28) 40%, rgb(0 0 0 / .62)); }
/* The page by day, in miniature. */
.mini.day { background: var(--day); color: #1b1a19; }
.mini.day .mini-hero { padding-bottom: 30px; background: radial-gradient(70% 60% at 15% 10%, color-mix(in srgb, var(--primary), #fff 25%), transparent 70%), radial-gradient(60% 55% at 95% 25%, color-mix(in srgb, var(--accent) 50%, transparent), transparent 70%), var(--primary); color: var(--on-primary); }
.mini.day .mini-hero.has-cover { color: #fff; }
.mini.day .mini-hero::after { display: none; }
.mini.day .mini-hero .st { background: color-mix(in srgb, var(--on-primary) 12%, transparent); border-color: color-mix(in srgb, var(--on-primary) 20%, transparent); }
.mini.day .mini-hero.has-cover .st { background: rgb(255 255 255 / .12); border-color: rgb(255 255 255 / .2); }
.mini.day .mini-body { position: relative; margin-top: -16px; padding-top: 14px; background: var(--day); border-radius: 18px 18px 0 0; }
.mini.day .mini-svc { background: #fff; border-color: rgb(0 0 0 / .06); }
.mini.day .mini-svc .d { color: #8a857d; }
.mini.day .mini-svc .p { color: var(--accent-ink); }
.mini.day .mini-svc .e { color: var(--accent-ink); background: color-mix(in srgb, var(--accent-ink) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-ink) 22%, transparent); }
.mini.day .mini-team img, .mini.day .mini-team .ph { background: #e6e2da; color: #8a857d; }
.mini.day .mini-empty { color: #9a958d; }
.mini.day .mini-cta { color: var(--on-accent-ink); background: linear-gradient(135deg, color-mix(in srgb, var(--accent-ink), #fff 16%), var(--accent-ink) 50%, color-mix(in srgb, var(--accent-ink), #000 14%)); box-shadow: 0 10px 26px -8px color-mix(in srgb, var(--accent-ink) 60%, transparent), inset 0 1px 0 rgb(255 255 255 / .3); }
/* The launch screen, in miniature. */
.mini-splash { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; background: var(--night); color: #f7f4ef; font-family: var(--font); }
.mini-splash { background: radial-gradient(60% 40% at 50% 44%, color-mix(in srgb, var(--accent-lift) 14%, transparent), transparent 70%), var(--night); }
/* By day the app opens on its hero: the salon's main colour. */
.mini-splash.day { background: radial-gradient(60% 40% at 50% 44%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%), var(--primary); color: var(--on-primary); }
.mini-splash .mk { position: relative; width: 84px; height: 84px; margin-top: -40px; margin-bottom: 12px; }
.mini-splash .mini-lights { --ring: 60px; inset: -22px; animation: spin 40s linear infinite; }
.mini-splash .app-icon { position: relative; --s: 84px; border-radius: 24px; }
.mini-splash .nm { font-size: 19px; font-weight: 700; padding-block: .06em; }
.mini-splash:not(.day) .nm { background: linear-gradient(180deg, #fff 40%, color-mix(in srgb, var(--accent-lift), #fff 35%)); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* An app icon drawn the way the server renders it: own icon, or logo on a background. */
.app-icon.own img { width: 100%; height: 100%; object-fit: cover; }
.app-icon.on-bg { background: var(--icon-bg); }
.app-icon.on-bg img { width: 84%; height: 84%; object-fit: contain; }

.home-screen { position: absolute; inset: 0; background:
  radial-gradient(90% 60% at 20% 10%, color-mix(in srgb, var(--accent) 55%, transparent), transparent 70%),
  radial-gradient(80% 60% at 90% 90%, color-mix(in srgb, var(--primary) 80%, #000), transparent 70%),
  linear-gradient(160deg, color-mix(in srgb, var(--primary) 70%, #333), color-mix(in srgb, var(--primary) 50%, #000)); color: #fff; }
.home-grid { position: absolute; top: 74px; inset-inline: 20px; display: grid; grid-template-columns: repeat(4, 1fr); row-gap: 20px; direction: ltr; }
.home-grid > div { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.home-grid .ghost { width: 54px; height: 54px; border-radius: 23%; background: rgb(255 255 255 / .16); backdrop-filter: blur(4px); }
.home-grid .lbl { width: 34px; height: 6px; border-radius: 3px; background: rgb(255 255 255 / .28); }
.home-grid .mine .app-icon { --s: 54px; animation: bounce 2.4s var(--spring) infinite; box-shadow: 0 0 0 3px rgb(255 255 255 / .5), 0 12px 28px -6px rgb(0 0 0 / .55); }
.home-grid .mine .nm { font-size: 10.5px; font-weight: 600; max-width: 70px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; }
@keyframes bounce { 0%, 70%, 100% { transform: translateY(0); } 80% { transform: translateY(-6px); } 90% { transform: translateY(0); } }
.home-dock { position: absolute; bottom: 14px; inset-inline: 12px; height: 78px; border-radius: 28px; background: rgb(255 255 255 / .2); backdrop-filter: blur(10px); display: flex; align-items: center; justify-content: space-around; }
.home-dock .ghost { width: 52px; height: 52px; border-radius: 23%; background: rgb(255 255 255 / .22); }
.home-clock { position: absolute; top: 44px; inset-inline: 0; text-align: center; font-size: 12px; opacity: .8; direction: ltr; }

.preview-tabs { width: 240px; margin: 0 auto 18px; }
/* In a sheet (the owner's preview, the customer's install steps) the phone sits centred. */
.sheet .phone-wrap { margin-inline: auto; }

/* ==========================================================================
   Login (aurora)
   ========================================================================== */
.login { position: relative; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; padding: calc(24px + var(--safe-top)) 20px calc(24px + var(--safe-bottom)); overflow: hidden; isolation: isolate; }
.aurora { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.aurora i { position: absolute; width: 70vmax; height: 70vmax; border-radius: 50%; filter: blur(80px); opacity: .5; animation: drift 18s ease-in-out infinite alternate; }
.aurora i:nth-child(1) { background: var(--brand); top: -35vmax; inset-inline-end: -25vmax; }
.aurora i:nth-child(2) { background: var(--glow-3); bottom: -40vmax; inset-inline-start: -30vmax; opacity: .38; animation-duration: 24s; }
.aurora i:nth-child(3) { background: #c026d3; top: 30%; inset-inline-start: 40%; width: 40vmax; height: 40vmax; opacity: .16; animation-duration: 30s; }
@keyframes drift { to { transform: translate(-8vmax, 6vmax) scale(1.15); } }
/* Sign-in: softer, smaller lights that fade at the edges, so the page reads as a lit
   room rather than a slab of colour. */
.login .aurora { -webkit-mask-image: radial-gradient(130% 110% at 50% 45%, #000 35%, transparent 80%); mask-image: radial-gradient(130% 110% at 50% 45%, #000 35%, transparent 80%); }
.login .aurora i { width: 46vmax; height: 46vmax; filter: blur(110px); opacity: .55; }
.login .aurora i:nth-child(1) { top: -16vmax; inset-inline-end: -12vmax; }
.login .aurora i:nth-child(2) { top: auto; bottom: -18vmax; inset-inline-start: -14vmax; opacity: .42; }
.login .aurora i:nth-child(3) { top: 38%; inset-inline-start: 36%; width: 30vmax; height: 30vmax; opacity: .18; }
.login-grid { width: 100%; }
.login-inner { width: 100%; max-width: 400px; margin: 0 auto; }
.login-help { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 12px; text-align: center; }
.login-help .team-hint { margin: 0; font-size: 12.5px; color: var(--text-3); }
.login-help .forgot { font-size: 13.5px; color: var(--text-2); }
.login-help .forgot:hover { color: var(--text); }
.login-foot:has(> :only-child) { justify-content: center; }
.login-legal { margin-top: 26px; }
.login-legal .legal-links { font-size: 12.5px; }
.login-show { display: none; }
/* Wide screens: the form at the inline start, a showcase at the inline end. */
@media (min-width: 1024px) {
  .login.has-show { padding: 20px; }
  .login.has-show .login-grid { display: grid; grid-template-columns: minmax(380px, 460px) minmax(0, 1fr); gap: clamp(32px, 5vw, 88px); align-items: center; max-width: 1280px; min-height: calc(100dvh - 40px); margin: 0 auto; }
  .login.has-show .login-inner { padding-block: 24px; }
  .login-show { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 30px; align-self: stretch; min-height: 600px; padding: 48px 32px; border-radius: 36px; border: 1px solid var(--line-2);
    background: radial-gradient(70% 55% at 50% 42%, color-mix(in srgb, var(--glow-1, var(--brand)) 20%, transparent), transparent 70%), radial-gradient(60% 50% at 80% 100%, color-mix(in srgb, var(--glow-3, var(--brand)) 16%, transparent), transparent 70%), color-mix(in srgb, var(--surface) 50%, transparent);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / .06), 0 40px 80px -40px rgb(0 0 0 / .8); }
  /* A fine dot grid, fading out from the middle, like a studio floor. */
  .login-show::before { content: ''; position: absolute; inset: 0; z-index: -1; background-image: radial-gradient(circle, rgb(255 255 255 / .09) 1px, transparent 1.4px); background-size: 22px 22px; -webkit-mask-image: radial-gradient(60% 55% at 50% 45%, #000, transparent); mask-image: radial-gradient(60% 55% at 50% 45%, #000, transparent); }
  .ls-caption { max-width: 420px; text-align: center; }
  .ls-caption h2 { font-size: 22px; line-height: 1.4; }
  .ls-caption p { margin-top: 6px; color: var(--text-2); font-size: 15px; }
}
/* The salon's app, standing in a ring of its own light. */
.ls-stage { position: relative; display: grid; place-items: center; }
.ls-ring { position: absolute; width: 380px; height: 380px; border-radius: 50%; background: conic-gradient(transparent, color-mix(in srgb, var(--accent-lift, var(--brand)) 55%, transparent), transparent 40%, color-mix(in srgb, var(--primary-lift, var(--glow-3)) 45%, transparent), transparent 75%); filter: blur(40px); opacity: .7; }
.ls-phone { position: relative; filter: drop-shadow(0 40px 60px rgb(0 0 0 / .55)); transition: opacity .5s; }
.ls-phone.ls-wait { opacity: .35; }
.ls-blank { position: absolute; inset: 0; background: var(--night, var(--surface)); }
/* The platform: its mark at the centre, salons in orbit, a dashboard rising. */
.ls-orbit { position: relative; width: 420px; height: 420px; display: grid; place-items: center; }
.ls-orbit .orb { position: absolute; border-radius: 50%; border: 1px solid var(--line-2); }
.ls-orbit .r1 { inset: 0; border-style: dashed; opacity: .6; }
.ls-orbit .r2 { inset: 70px; }
.ls-orbit .r3 { inset: 140px; background: radial-gradient(closest-side, color-mix(in srgb, var(--glow-1) 26%, transparent), transparent); border-color: transparent; }
.ls-core { --s: 96px; position: relative; z-index: 2; border-radius: 30px; box-shadow: 0 24px 60px -16px var(--brand-glow), 0 0 0 1px rgb(255 255 255 / .14) inset; }
.ls-spin { position: absolute; inset: 0; }
.ls-spin.b { inset: 70px; }
.ls-sat { position: absolute; display: block; }
.ls-sat .app-icon { --s: 46px; border-radius: 14px; color: #fff; box-shadow: 0 14px 30px -10px rgb(0 0 0 / .6), 0 0 0 1px rgb(255 255 255 / .12) inset; }
.ls-sat .app-icon svg { width: 64%; height: 64%; }
.ls-sat.s1 { top: -23px; left: calc(50% - 23px); }
.ls-sat.s2 { top: 9%; right: 16%; }
.ls-sat.s3 { top: 18px; left: 0; }
.ls-sat.s4 { bottom: -10px; left: calc(50% - 23px); }
.ls-sat.s5 { top: 30%; right: -23px; }
.ls-sat.s1 .app-icon { background: linear-gradient(135deg, #f5d06f, #b7791f); }
.ls-sat.s2 .app-icon { background: linear-gradient(135deg, #f472b6, #9d174d); }
.ls-sat.s3 .app-icon { background: linear-gradient(135deg, #34d399, #065f46); }
.ls-sat.s4 .app-icon { background: linear-gradient(135deg, #60a5fa, #1e3a8a); }
.ls-sat.s5 .app-icon { background: linear-gradient(135deg, #e5e7eb, #4b5563); }
.ls-board { position: absolute; z-index: 3; bottom: 4px; inset-inline-end: -72px; width: 220px; padding: 14px; border-radius: 20px; background: color-mix(in srgb, var(--surface-2) 82%, transparent); border: 1px solid var(--line-2); box-shadow: var(--shadow-lg); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); }
.ls-board-top { display: flex; align-items: center; gap: 6px; }
.ls-board-top i { width: 34px; height: 6px; border-radius: 99px; background: var(--line-2); }
.ls-board-top b { margin-inline-start: auto; width: 46px; height: 16px; border-radius: 99px; background: color-mix(in srgb, var(--ok) 24%, transparent); }
/* On 1024-1239px laptops the showcase column is 470-670px wide: the orbit and its
   board shrink with it (the negative block margins take back the space the scale frees). */
@media (min-width: 1024px) and (max-width: 1139px) {
  .ls-orbit { scale: .78; margin-block: -46px; }
  .ls-board { inset-inline-end: -28px; }
}
@media (min-width: 1140px) and (max-width: 1239px) {
  .ls-orbit { scale: .88; margin-block: -25px; }
  .ls-board { inset-inline-end: -40px; }
}
.ls-bars { display: flex; align-items: flex-end; gap: 5px; height: 72px; margin-top: 12px; direction: ltr; }
.ls-bars i { flex: 1; height: calc(var(--v) * 100%); border-radius: 3px; background: linear-gradient(to top, var(--glow-3), var(--glow-1)); opacity: calc(.45 + var(--v) * .55); }
@media (prefers-reduced-motion: no-preference) {
  /* The ring turns as a layer (a transform), not by repainting its gradient. */
  .ls-ring { animation: ls-turn 14s linear infinite; }
  .ls-phone:not(.ls-wait) { animation: ls-float 7s ease-in-out infinite; }
  .ls-spin.a { animation: ls-turn 60s linear infinite; }
  .ls-spin.b { animation: ls-turn 42s linear infinite reverse; }
  .ls-spin.a .ls-sat { animation: ls-turn 60s linear infinite reverse; }
  .ls-spin.b .ls-sat { animation: ls-turn 42s linear infinite; }
  .ls-bars i { transform-origin: bottom; animation: bar-grow .9s var(--ease-out) both; animation-delay: calc(.4s + var(--i) * 60ms); }
}
@keyframes ls-float { 50% { transform: translateY(-12px) rotate(-1deg); } }
@keyframes ls-turn { to { transform: rotate(360deg); } }
.login-brand { text-align: center; margin-bottom: 26px; }
.login-brand .app-icon { --s: 84px; margin: 0 auto 18px; box-shadow: 0 20px 50px -14px var(--brand-glow), 0 0 0 1px rgb(255 255 255 / .1); }
.login-brand h1 { font-size: 30px; }
.login-brand p { color: var(--text-2); margin-top: 6px; }
.login .card { padding: 20px; background: color-mix(in srgb, var(--surface) 78%, transparent); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); }
.login .btn-primary { margin-top: 18px; }
.login-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 18px; }
.phone-input { display: flex; gap: 8px; }
/* Numbers read left to right, so the country code sits on the left in Arabic too. */
[dir='rtl'] .phone-input { flex-direction: row-reverse; }
.phone-input .f > input { text-align: left !important; }
.phone-input .cc { display: grid; place-items: center; flex: none; min-width: 72px; height: 60px; padding: 0 12px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); font-weight: 500; direction: ltr; }
.phone-input .f { flex: 1; margin: 0; }
.pw-toggle { position: absolute; inset-inline-end: 8px; top: 8px; width: 44px; height: 44px; border: 0; border-radius: 12px; background: transparent; color: var(--text-3); display: grid; place-items: center; cursor: pointer; }
.f.has-toggle > input { padding-inline-end: 56px; }

/* ==========================================================================
   Platform admin
   ========================================================================== */
.admin-salon { display: flex; align-items: center; gap: 14px; padding: 14px 16px; }
.admin-salon .app-icon { --s: 50px; }
.admin-salon .name { font-weight: 600; }
.admin-salon a { color: var(--text-2); font-size: 13px; direction: ltr; unicode-bidi: isolate; }
.admin-salon a:hover { color: var(--brand); }
.admin-salon .owner { font-size: 12.5px; color: var(--text-3); }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.stats .card { padding: 14px; }
.stats b { display: block; font-size: 26px; line-height: 1.1; }
.stats span { font-size: 12.5px; color: var(--text-2); }
.url-preview { font-size: 13px; color: var(--brand); margin-top: 6px; direction: ltr; text-align: end; }
/* The platform settings sheet: a card that opens the landing page. */
.platform-link { display: flex; align-items: center; gap: 14px; color: inherit; text-decoration: none; transition: border-color .2s, background .2s; }
.platform-link:hover { border-color: var(--line-2); background: var(--surface-2); }
.platform-link .app-icon { --s: 44px; flex: none; border-radius: 14px; }
.platform-link .name { font-weight: 600; }
.platform-link .sub { margin-top: 2px; font-size: 13px; color: var(--text-2); }
.platform-link > .icon { flex: none; width: 18px; height: 18px; }
[dir='ltr'] .url-preview { text-align: start; }

/* ==========================================================================
   Desktop: sidebar + content + live preview
   ========================================================================== */
@media (min-width: 1080px) {
  .studio { display: grid; grid-template-columns: 260px minmax(0, 1fr) 400px; }
  .s-tabbar { display: none; }
  .s-side { display: flex; flex-direction: column; gap: 4px; position: sticky; top: 0; height: 100dvh; padding: 22px 14px; border-inline-end: 1px solid var(--line); background: color-mix(in srgb, var(--bg) 70%, transparent); }
  .s-side .identity { padding: 4px 8px 22px; flex: none; }
  .s-side .side-walkin { flex: none; margin: 0 4px 14px; height: 46px; }
  .s-side .side-label { margin: 14px 14px 4px; font-size: 12px; font-weight: 600; color: var(--text-3); }
  .s-side .side-walkin + .side-label { margin-top: 4px; }
  /* Until the salon opens: the way back into the setup guide, its progress a lit pole. */
  .s-side .side-guide {
    flex: none; display: flex; align-items: center; gap: 12px; margin: 0 4px 14px; padding: 10px 14px 10px 10px; border-radius: 16px; color: var(--text);
    background: radial-gradient(120% 90% at 20% 0%, var(--light-wash), transparent 60%), var(--surface); border: 1px solid var(--light-line);
    box-shadow: inset 0 1px 0 var(--rim-hi), 0 0 26px -14px var(--light-glow); transition: background-color .2s, transform var(--t-release) var(--spring-soft);
  }
  [dir='rtl'] .s-side .side-guide { padding: 10px 10px 10px 14px; }
  .s-side .side-guide:active { transform: scale(.97); transition-duration: var(--t-press); }
  .s-side .side-guide + .side-label { margin-top: 4px; }
  .side-guide .tile { width: 36px; height: 36px; border-radius: 11px; }
  .side-guide .tile .icon { width: 18px; height: 18px; }
  .side-guide .grow { display: grid; gap: 7px; min-width: 0; }
  .side-guide .lbl { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 14px; font-weight: 600; }
  .side-guide-bar { position: relative; display: block; height: 4px; border-radius: 4px; overflow: hidden; overflow: clip; background: var(--surface-3); }
  .side-guide-bar > i { position: absolute; inset: 0; overflow: hidden; overflow: clip; border-radius: inherit; translate: calc((var(--p, 0) - 1) * 100%) 0; box-shadow: 0 0 8px var(--light-glow); }
  /* Nothing done yet: the fill is out of sight, and its stripes stand still. */
  .side-guide.empty .pole-stripes { animation: none; }
  [dir='rtl'] .side-guide-bar > i { translate: calc((1 - var(--p, 0)) * 100%) 0; }
  .side-guide > b { flex: none; font-size: 13px; font-weight: 600; color: var(--light-hi); font-variant-numeric: tabular-nums; direction: ltr; }
  /* The sidebar's walk-in is the one primary walk-in on a wide screen: Home keeps its booking. */
  .home-actions .home-walkin { display: none; }
  .home-actions { grid-template-columns: minmax(0, 1fr); }
  .s-side a.nav { display: flex; align-items: center; gap: 12px; height: 46px; padding: 0 14px; border-radius: 14px; color: var(--text-2); font-weight: 500; transition: background-color .2s, color .2s; position: relative; }
  .s-side a.nav:hover { background: var(--surface); color: var(--text); }
  .s-side a.nav.active { color: var(--text); }
  .s-side a.nav.active .icon { color: var(--light-hi); filter: drop-shadow(0 0 8px var(--light-glow)); }
  .s-side a.nav .badge-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); margin-inline-start: auto; }
  .s-side .spacer { flex: 1; }
  .studio:not(.admin) .s-header { display: none; }
  .s-page { padding: 44px 40px 80px; max-width: 720px; }
  .studio.admin .s-page { padding-top: 8px; }
  .s-preview { display: flex; flex-direction: column; align-items: center; justify-content: center; position: sticky; top: 0; height: 100dvh; border-inline-start: 1px solid var(--line); background: radial-gradient(60% 50% at 50% 45%, color-mix(in srgb, var(--brand) 14%, transparent), transparent 70%); }
  .s-preview .eyebrow { margin-bottom: 14px; }
  .savebar { bottom: 24px; inset-inline: auto; left: calc(50% - 70px); transform: translateX(-50%); width: 520px; margin: 0; }
  [dir='rtl'] .savebar { left: calc(50% + 70px); }
  .brand-stage { display: none; }
  .toast { top: 20px; }
  /* The toast rises over the middle column, like the savebar. */
  [data-theme='studio'] body:has(.s-tabbar) > .toast { bottom: 24px; left: calc(50% - 70px); }
  [data-theme='studio'][dir='rtl'] body:has(.s-tabbar) > .toast { left: calc(50% + 70px); }
  /* A barber's studio has no preview column: his toast rises over his schedule, at the bottom (no dock here). */
  [data-theme='studio'] body:has(.sched-dock) > .toast { bottom: 24px; left: calc(50% + 120px); }
  [data-theme='studio'][dir='rtl'] body:has(.sched-dock) > .toast { left: calc(50% - 120px); }
  /* With unsaved changes the savebar holds the bottom: the toast rises just above it
     (24px offset + 62px bar + 12px gap) instead of covering its text and buttons. */
  [data-theme='studio'] body:has(> .savebar) > .toast { bottom: 98px; }
  body:has(> .savebar) .s-page { padding-bottom: 140px; }
  /* Launched, Home is about the day: it takes the preview's column too (while setting
     up, the preview stays, as it shows the owner's changes). */
  .studio[data-page='home'][data-launched] .s-preview { display: none; }
  .studio[data-page='home'][data-launched] .s-main { grid-column: 2 / -1; }
  .studio[data-page='home'][data-launched] .s-page { max-width: 1120px; }
  .team-grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
  .studio.admin { display: block; }
  .studio.admin .s-header .identity { display: flex; }
  .studio.admin .s-header { max-width: 800px; margin: 0 auto; }
}
@media (min-width: 1080px) and (max-width: 1279px) {
  .studio { grid-template-columns: 230px minmax(0, 1fr) 340px; }
  .s-preview :is(.phone-wrap, .pv-scan-band) { --scale: .82 !important; }
  /* Five palettes across a 430px column: a little less side padding keeps "Burgundy" whole. */
  .s-page .scroller.palettes .palette { padding-inline: 6px; }
}
@media (min-width: 1280px) {
  .studio:not(.admin) .s-page { max-width: 920px; }
  /* A launched Home in two columns: the day on one side (the actions, what needs the
     owner, today's visits), the takings and the link on the other. The DOM keeps the
     phone's order, so what is read and tabbed follows the eye. The takings span a
     flexible row, so a long card grows that row, not the gaps between the day's parts. */
  .home.is-launched {
    display: grid; grid-template-columns: minmax(0, 1fr) 380px; grid-template-rows: auto auto auto 1fr auto; column-gap: 28px; align-items: start;
    grid-template-areas: 'head head' 'actions takings' 'attention takings' 'today takings' 'today link';
  }
  .home.is-launched > .home-head { grid-area: head; }
  .home.is-launched > .home-actions { grid-area: actions; margin-top: 26px; }
  .home.is-launched > .home-attention { grid-area: attention; }
  .home.is-launched > .takings-section { grid-area: takings; margin-top: 26px; }
  .home.is-launched > .today-section { grid-area: today; }
  /* Under the takings; when the day runs longer, level with its end. */
  .home.is-launched > .link-row { grid-area: link; align-self: end; margin-top: 16px; }
}
/* On a wide screen the owner's short strips (palettes, presets, chips) wrap inside
   the column instead of scrolling sideways under a hidden scrollbar. */
@media (min-width: 1080px) {
  .s-page .scroller.fit { --bleed: 0px; flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; animation: none; }
  /* Thirteen palettes: a set column count (5+5+3, then 7+6 from 1400px) never leaves
     one alone on its last row, as auto-fill's 4 or 6 columns did. */
  .s-page .scroller.palettes { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .s-page .scroller.palettes .palette { width: auto; }
}
@media (min-width: 1400px) {
  .s-page .scroller.palettes { grid-template-columns: repeat(7, minmax(0, 1fr)); }
}
@media (min-width: 700px) {
  .sheet .scroller.fit { --bleed: 0px; flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; animation: none; }
}

/* ==========================================================================
   Booking (customer flow, booking page) and shared slot pickers
   ========================================================================== */
/* The sheet's frame, the chair concierge: back, the rail of steps and close on one row;
   under them the question, numbered, with its line of help; the step; and the customer's
   ticket at the foot, filling in as he chooses. A light falls from above, as at the mirror. */
.book-sheet { isolation: isolate; overflow: clip; }
.book-sheet::before {
  content: ''; position: absolute; inset: 0 0 auto; z-index: -1; height: 240px; border-radius: inherit; pointer-events: none;
  background: radial-gradient(80% 210px at 50% 0, color-mix(in srgb, var(--light) 12%, transparent), transparent 78%);
}
.book-sheet .sheet-head {
  position: relative; z-index: 3; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 0 8px;
  padding: 6px 12px 14px; transition: box-shadow .25s;
}
.book-sheet.scrolled .sheet-head { box-shadow: 0 1px 0 var(--line), 0 12px 22px -16px rgb(0 0 0 / .65); }
/* Kept in its place on the first step, so the rail never shifts; just not there to press. */
.bk-back.off { visibility: hidden; pointer-events: none; }
.book-sheet .sheet-body { overflow-x: hidden; }
.book-sheet .sheet-foot .btn-primary { min-width: 0; }

/* The rail: a lit node for each step done (a way back to it), the ringed one now (it pings
   once as it arrives), dim numbers after. The way into the step now is a short barber's
   pole that fills as the step comes in; the ways already walked are lit. */
.book-rail { display: flex; align-items: flex-start; justify-content: center; min-width: 0; margin: 0; padding: 0; list-style: none; }
.br-step { flex: none; display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 26px; }
.br-step .step-node { --sn: 26px; transition: background-color .3s, box-shadow .3s, color .3s, transform .2s var(--spring); }
.br-step button.step-node { padding: 0; border: 0; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.br-step button.step-node:active { transform: scale(.88); }
@media (hover: hover) { .br-step button.step-node:hover { box-shadow: 0 0 0 4px var(--light-wash), 0 0 14px -2px var(--light-glow); } }
.br-step.next .step-node { background: transparent; }
.br-lbl { font-size: 11px; line-height: 1.2; color: var(--text-2); white-space: nowrap; }
.br-step.now .br-lbl { color: var(--text); font-weight: 600; }
.br-link { position: relative; flex: 1 1 0; min-width: 12px; max-width: 64px; height: 2px; margin: 12px 4px 0; overflow: hidden; overflow: clip; border-radius: 2px; background: var(--line-2); }
.br-link.done { background: var(--light); box-shadow: 0 0 6px var(--light-glow); }
.br-link.live { height: 4px; margin-top: 11px; background: var(--surface-3); box-shadow: 0 0 10px -2px var(--light-glow); }
.br-fill { position: absolute; inset: 0; overflow: hidden; overflow: clip; border-radius: inherit; }
.br-link.fill .br-fill { animation: br-fill .4s var(--ease-out) both; }
/* By day the pole's white would vanish into the white sheet and the cream page: a warmer
   white, and the tube's edge drawn over its stripes. */
[data-theme='public'][data-page='day'] :is(.br-link.live, .jn-spine) { --pole-white: #ddd5c6; }
[data-theme='public'][data-page='day'] .br-link.live::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgb(20 18 16 / .22); pointer-events: none; }
[dir='rtl'] .br-link.fill .br-fill { animation-name: br-fill-rtl; }
@keyframes br-fill { from { clip-path: inset(0 100% 0 0); } }
@keyframes br-fill-rtl { from { clip-path: inset(0 0 0 100%); } }
/* On a phone the numbers are enough: the step's name is still read out. */
@media (max-width: 559px) {
  .br-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* The question: its number in the light (it turns like the counter at the front desk),
   the words, and a line of help. */
.bk-q { grid-column: 1 / -1; min-width: 0; padding: 12px 8px 0; }
.bk-q-no { display: block; height: 1.4em; overflow: hidden; overflow: clip; font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--light); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bk-q-no::before { content: ''; display: inline-block; width: 18px; height: 1px; margin-inline-end: 8px; vertical-align: middle; background: currentColor; opacity: .6; }
:lang(en) .bk-q-no { text-transform: uppercase; letter-spacing: .12em; }
.bk-q-d { display: inline-grid; height: 1.4em; overflow: hidden; overflow: clip; vertical-align: top; }
.bk-q-d b { grid-area: 1 / 1; font-weight: inherit; direction: ltr; unicode-bidi: isolate; }
.book-sheet .bk-q h2 { margin-top: 4px; font-size: 22px; font-weight: 700; line-height: 1.35; border-radius: 8px; outline-offset: 4px; }
.bk-q-help { margin-top: 4px; max-width: 46ch; font-size: 14px; line-height: 1.55; color: var(--text-2); }
.bk-q-help.warn { color: var(--warn); }
.bk-q-help.in { animation: bk-help .35s var(--ease-out) .12s both; }
@keyframes bk-help { from { opacity: 0; translate: 0 4px; } }

/* The ticket at the sheet's foot: what is chosen so far (a dashed place, numbered, for what
   is not), each a way back to its step; the price on its stub, past a perforation cut
   like the ticket's own. A choice flies in and lands with a stamp. */
.bk-dock { position: relative; z-index: 1; flex: none; display: flex; margin: 0 12px calc(10px + var(--safe-bottom)); filter: drop-shadow(0 16px 24px rgb(0 0 0 / .42)); transition: translate .3s var(--ease-out), opacity .3s; }
.dk-main, .dk-total {
  position: relative; height: 64px;
  background: var(--pane-edge), linear-gradient(165deg, color-mix(in srgb, var(--text) 7%, transparent), transparent 60%), var(--surface);
  box-shadow: inset 0 0 0 1px var(--line-2);
}
.dk-main { flex: 1 1 auto; min-width: 0; display: flex; align-items: stretch; padding: 0 4px; border-radius: 18px; }
.dk-total { flex: none; display: grid; align-content: center; justify-items: center; gap: 1px; padding: 0 14px 0 15px; border-start-start-radius: 0; border-end-start-radius: 0; border-start-end-radius: 18px; border-end-end-radius: 18px; }
.bk-dock.has-stub .dk-main { border-start-end-radius: 0; border-end-end-radius: 0; }
.bk-dock.has-stub .dk-main {
  -webkit-mask: radial-gradient(circle at 100% 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle at 100% 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
}
.dk-total, [dir='rtl'] .bk-dock.has-stub .dk-main {
  -webkit-mask: radial-gradient(circle at 0 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 0 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle at 0 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 0 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
}
[dir='rtl'] .dk-total {
  -webkit-mask: radial-gradient(circle at 100% 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle at 100% 0, transparent 7px, #000 7.5px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 7px, #000 7.5px) bottom / 100% 51% no-repeat;
}
.dk-total::before { content: ''; position: absolute; inset-block: 11px; inset-inline-start: 0; border-inline-start: 1.5px dashed var(--line-2); }
.dk-total b { display: flex; align-items: baseline; gap: 4px; font-size: 15px; font-weight: 600; color: var(--text); white-space: nowrap; }
.dk-total small { font-size: 10.5px; font-weight: 500; color: var(--text-2); }
.dk-slot { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; margin: 6px 0; padding: 0 7px; border: 0; border-radius: 13px; background: none; color: var(--text); font: inherit; text-align: start; }
button.dk-slot { cursor: pointer; transition: background-color .2s; }
@media (hover: hover) { button.dk-slot:hover { background: var(--light-wash); } }
button.dk-slot:active .dk-ic { transform: scale(.9); }
.dk-slot + .dk-slot::before { content: ''; position: absolute; inset-block: 10px; inset-inline-start: 0; border-inline-start: 1px dashed var(--line-2); }
.dk-ic {
  position: relative; flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  background: var(--surface-2); color: var(--light); box-shadow: inset 0 0 0 1px var(--light-line), 0 0 12px -4px var(--light-glow);
  transition: transform .2s var(--spring);
}
.dk-ic .icon { width: 15px; height: 15px; filter: var(--glyph-glow); }
.dk-ic .avatar { width: 28px; height: 28px; font-size: 11px; }
.dk-slot.empty .dk-ic { background: none; box-shadow: none; border: 1.5px dashed var(--line-2); color: var(--text-3); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.dk-tx { display: grid; min-width: 0; line-height: 1.3; }
.dk-v { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 13px; font-weight: 600; }
.dk-l { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 10.5px; color: var(--text-3); }
.dk-slot.empty { flex-shrink: 3; }
.dk-slot.empty .dk-v { font-weight: 500; color: var(--text-3); }
.dk-look { flex: none; display: grid; place-items: center; padding-inline: 6px 4px; }
.dk-look img { width: 30px; height: 40px; border-radius: 9px; object-fit: cover; box-shadow: 0 0 0 1px var(--light-line); }
/* On its way: the place waits for the flying choice, then stamps (a ring of light goes out). */
.dk-slot.incoming > * { opacity: 0; }
.dk-slot.stamp .dk-ic { animation: bk-stamp .38s var(--spring); }
.dk-slot.stamp .dk-ic::after { content: ''; position: absolute; inset: -2px; border-radius: 50%; border: 2px solid var(--light); pointer-events: none; animation: bk-stamp-ring .55s var(--ease-out) both; }
.dk-slot.stamp .dk-tx { animation: bk-help .3s var(--ease-out) both; }
@keyframes bk-stamp { from { transform: scale(1.3); } }
@keyframes bk-stamp-ring { from { opacity: 1; transform: scale(.9); } to { opacity: 0; transform: scale(1.8); } }
/* A time taken by someone else meanwhile: its place shakes loose. */
.dk-slot.unstamp { animation: bk-shake .3s linear; }
@keyframes bk-shake { 20%, 60% { translate: 6px 0; } 40%, 80% { translate: -6px 0; } }
/* On the review the ticket sinks out of the sheet and the confirm button rises in its place. */
.bk-dock.leaving { position: absolute; inset-inline: 0; bottom: 0; translate: 0 110%; opacity: 0; pointer-events: none; }
.bk-dock.arriving { animation: bk-dock-in .35s var(--ease-out) both; }
@keyframes bk-dock-in { from { opacity: 0; translate: 0 16px; } }
.book-sheet .sheet-foot.rising { animation: bk-foot .3s var(--ease-out) .15s both; }
@keyframes bk-foot { from { opacity: 0; translate: 0 12px; } }
/* A narrow phone: the stub is just the price, an empty place just its number; once the
   time is chosen, the service and the barber are their icons and the time has the room. */
@media (max-width: 479px) {
  .bk-dock.full .dk-slot:not([data-k='time']) { flex: none; }
  .bk-dock.full .dk-slot:not([data-k='time']) .dk-tx { display: none; }
}
@media (max-width: 419px) {
  .dk-total .dk-l { display: none; }
}
@media (max-width: 379px) {
  .dk-slot .dk-l, .dk-slot.empty .dk-tx { display: none; }
  .dk-slot.empty { flex: 0 1 auto; }
  .dk-slot { gap: 7px; padding: 0 6px; }
  .dk-total { padding-inline: 12px 10px; }
}
/* A choice on its way to the ticket: a copy of it, over the sheet. */
.fly-ghost { position: fixed; z-index: 130; margin: 0; pointer-events: none; will-change: transform; animation: none !important; transition: none !important; }
/* The choice just made: lit, pressed in, while it flies. */
:is(.book-sheet .p-svc, .pick-card, .slot).picked { scale: .98; box-shadow: 0 0 0 2px var(--light), 0 0 22px -6px var(--light-glow); transition: scale .2s var(--ease-out), box-shadow .2s; }

/* The booking's steps as bars: the landing's printed booking keeps them. */
.book-progress { display: grid; grid-template-columns: repeat(var(--n, 4), 1fr); gap: 6px; margin-bottom: 18px; }
.book-progress i { position: relative; overflow: hidden; height: 4px; border-radius: 99px; background: var(--line-2); }
.book-progress i::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: var(--grad, var(--brand)); transform: scaleX(0); transform-origin: right; transition: transform .5s var(--ease-out); }
[dir='ltr'] .book-progress i::after { transform-origin: left; }
.book-progress i.on::after { transform: none; }

/* The choice so far rides on the main button: "Confirm · 2 JD deposit". */
.btn .btn-sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: 14px; font-weight: 500; opacity: .8; }
.btn .btn-sub::before { content: '·'; margin-inline-end: 8px; }
/* On a phone it rides under the button's word instead, so neither is cut short:
   "تأكيد الحجز" over "عربون 2 د.أ.". */
@media (max-width: 559px) {
  .book-sheet .sheet-foot .btn-primary:has(.btn-sub) { flex-direction: column; gap: 0; padding-inline: 14px; line-height: 1.3; }
  .book-sheet .sheet-foot .btn-primary .btn-sub { max-width: 100%; font-size: 12.5px; }
  .book-sheet .sheet-foot .btn-primary .btn-sub::before { content: none; }
}
/* Steps slide in from the way the customer is going. */
.bk-step.fwd { animation: bk-from-end .45s var(--ease-out); }
.bk-step.back { animation: bk-from-start .45s var(--ease-out); }
[dir='rtl'] .bk-step.fwd { animation-name: bk-from-start; }
[dir='rtl'] .bk-step.back { animation-name: bk-from-end; }
@keyframes bk-from-end { from { opacity: 0; transform: translateX(28px); } }
@keyframes bk-from-start { from { opacity: 0; transform: translateX(-28px); } }
/* "Not yet" reads as quiet, not as a broken gold slab; it warms up when ready. */
.book-sheet .btn-primary:disabled:not(.busy), .booking-page .btn-primary:disabled:not(.busy) { background: var(--surface-3); color: var(--text-3); box-shadow: inset 0 0 0 1px var(--line-2); opacity: 1; }
.book-sheet .btn-primary:disabled::before, .booking-page .btn-primary:disabled::before { display: none; }
.book-sheet .sheet-foot .btn-primary:enabled, .booking-page .btn-primary:enabled { animation: bk-ready .5s var(--ease-out); }
@keyframes bk-ready { from { filter: saturate(.2) brightness(.75); } }
@media (min-width: 700px) {
  /* The dialog keeps one size from step to step instead of jumping. */
  .sheet.book-sheet.tall { height: min(740px, 90dvh); }
}

/* Step 1: the menu as on the salon's page, one compact card per row (the whole card is
   the target: its icon flies to the ticket). */
.book-sheet .p-services { grid-template-columns: minmax(0, 1fr); gap: 10px; }
.book-sheet .p-services > .p-svc:last-child:nth-child(odd) { grid-column: auto; }
.book-sheet .p-svc { gap: 12px; padding: 12px 14px; border-radius: 18px; }
.book-sheet .p-svc-e { width: 40px; height: 40px; }
.book-sheet .p-svc-e .icon { width: 21px; height: 21px; }
.book-sheet .p-svc .n { font-size: 15.5px; }
.book-sheet .p-svc .d { -webkit-line-clamp: 1; }
.book-sheet .p-svc .m { margin-top: 6px; }
.book-sheet .p-svc.on { border-color: var(--brand-line); box-shadow: var(--shadow), 0 0 0 3px var(--brand-soft); }

.pick-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.pick-card { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 18px 10px 16px; border-radius: 20px; background: var(--surface); border: 1px solid var(--line); cursor: pointer; text-align: center; box-shadow: var(--shadow); transition: transform .25s var(--spring), border-color .2s; }
.pick-card:hover { border-color: var(--brand-line); transform: translateY(-2px); }
.pick-card:active { transform: scale(.96); }
.pick-card .avatar.lg { width: 64px; height: 64px; font-size: 22px; }
.pick-card .tile { width: 64px; height: 64px; border-radius: 50%; }
.pick-card .nm { font-weight: 600; font-size: 15px; }
.pick-card .sub { font-size: 12px; color: var(--text-2); line-height: 1.4; }
.pick-card.anyone { background: linear-gradient(160deg, var(--brand-soft), var(--surface) 70%); border-color: var(--brand-line); }
.pick-card.on { border-color: var(--brand); box-shadow: var(--shadow), 0 0 0 3px var(--brand-soft); }
/* When someone is next free: a small two-line chip, the label over the time; it sits
   at the card's foot, so the chips of a row line up whatever the titles above. */
.pick-next { display: grid; justify-items: center; align-content: center; gap: 1px; max-width: 100%; min-height: 42px; margin-top: auto; padding: 5px 12px; border-radius: 12px; background: var(--surface-2); line-height: 1.35; }
.pick-next .lbl { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-3); }
/* The day and the time each hold together; on a narrow card the time takes its own line. */
.pick-next b { display: flex; flex-wrap: wrap; justify-content: center; column-gap: .3em; font-size: 12.5px; font-weight: 600; color: var(--text); }
.pick-next b > span { white-space: nowrap; }
.pick-next.none { min-height: 0; padding-block: 6px; }
.pick-next:has(.skel) { gap: 6px; background: none; }
.pick-next .skel { width: 64px; height: 10px; border-radius: 99px; }
.pick-next .skel + .skel { width: 92px; height: 12px; }
.pick-next .dot { width: 6px; height: 6px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 20%, transparent); }
.pick-card.anyone .pick-next { background: color-mix(in srgb, var(--brand) 10%, var(--surface-2)); }
/* "Any barber" first, across the row and suggested: the team's faces, and who is free
   soonest and when. */
.pick-card.anyone.wide { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 14px; padding: 16px; text-align: start; box-shadow: var(--shadow), inset 0 0 0 1px var(--light-line), 0 0 26px -16px var(--light-glow); }
.pick-card.anyone.wide:hover { transform: translateY(-1px); }
.pick-card.anyone.wide:active { transform: scale(.98); }
.pick-card.anyone.wide > .avatar-stack { flex: none; }
.pick-card.anyone.wide > .avatar-stack .avatar { width: 42px; height: 42px; font-size: 15px; border-color: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.pick-card.anyone.wide > .avatar-stack .avatar + .avatar { margin-inline-start: -15px; }
.pk-any { flex: 1; min-width: 0; display: grid; gap: 5px; }
.pk-any .nm { font-size: 16px; }
.pick-card.anyone.wide .pick-next { justify-items: start; min-height: 0; margin: 0; padding: 0; background: none; }
.pick-card.anyone.wide .pick-next .lbl { align-items: flex-start; font-size: 12.5px; line-height: 1.45; color: var(--text-2); }
.pick-card.anyone.wide .pick-next .dot { margin-top: 6px; }
/* The soonest time, on its own line under who has it, in line with the words above. */
.pick-card.anyone.wide .pick-next b { justify-content: flex-start; padding-inline-start: 12px; }
.pick-card.anyone.wide .pick-next .skel { width: 150px; height: 12px; }
.pick-sugg { flex: none; align-self: flex-start; display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: 99px; background: var(--light-wash); box-shadow: inset 0 0 0 1px var(--light-line), 0 0 12px -4px var(--light-glow); color: var(--light-hi); font-size: 11.5px; font-weight: 600; white-space: nowrap; }

.day-strip { gap: 8px; padding-bottom: 8px; }
.day-chip { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 70px; padding: 10px 8px; border-radius: 18px; background: var(--surface); border: 1px solid var(--line); cursor: pointer; transition: background-color .2s, border-color .2s, transform .25s var(--spring), color .2s; }
.day-chip .dw { font-size: 11.5px; color: var(--text-2); white-space: nowrap; }
.day-chip .dn { font-size: 26px; font-weight: var(--w-figure); line-height: 1.15; font-variant-numeric: tabular-nums; }
.day-chip .dm { font-size: 11px; color: var(--text-3); }
.day-chip .badge { position: absolute; top: -6px; inset-inline-end: -4px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 99px; background: var(--grad, var(--brand)); color: var(--on-brand); font-size: 11px; font-weight: 700; display: grid; place-items: center; }
.day-chip:active { transform: scale(.95); }
/* A chosen day or time is lit like the main action: its fill and the light's neon rim. */
.day-chip.on { background: var(--grad, var(--brand)); border-color: transparent; color: var(--on-brand); box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), 0 0 0 1px var(--light-line), 0 0 16px -6px var(--light-glow), 0 10px 24px -12px var(--brand-glow); }
.day-chip.on .dw, .day-chip.on .dm { color: inherit; opacity: .85; }
.day-chip:disabled { opacity: .35; cursor: default; }
/* A day without times says why (closed, or fully booked) instead of just fading. */
.day-chip.noted:disabled { opacity: .55; background: transparent; border-style: dashed; }
.day-chip.noted .dm { font-size: 10.5px; white-space: nowrap; }

/* Step 3: the month above the days; days and group titles stay pinned while the
   times scroll (on a phone); a wide dialog shows the two weeks as a calendar. */
.bk-days { position: sticky; top: -4px; z-index: 2; margin: -4px -20px 0; padding: 4px 20px 8px; background: var(--bg-2); }
.bk-days-skel { height: 112px; border-radius: 18px; }
.bk-month { margin: 0 2px 8px; font-size: 13px; font-weight: 600; color: var(--text-2); }
/* What is left of last night's opening: "Tonight" over a moon, in place of a date. */
.book-sheet .day-chip.late { justify-content: center; background: linear-gradient(165deg, var(--brand-soft), var(--surface) 75%); border-color: var(--brand-line); }
.book-sheet .day-chip.late .dn { display: grid; place-items: center; height: 1.2em; color: var(--brand); }
.book-sheet .day-chip.late .dn .icon { width: .95em; height: .95em; }
.book-sheet .day-chip.late.on { background: var(--grad, var(--brand)); border-color: transparent; }
.book-sheet .day-chip.late.on .dn { color: inherit; }
.book-sheet .day-strip { margin-inline: -20px; padding-inline: 20px; scroll-padding-inline: 20px;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 20px, #000 calc(100% - 20px), transparent); mask-image: linear-gradient(to right, transparent, #000 20px, #000 calc(100% - 20px), transparent); }
.bk-slots { margin-top: 10px; }
/* The soonest free time, before any other: big and thin in the light, its day, who it is
   with, and one button that takes it. */
.bk-soon {
  position: relative; display: grid; justify-items: start; gap: 2px; margin-bottom: 4px; padding: 16px 18px 18px; border-radius: 22px; overflow: hidden; overflow: clip;
  background: radial-gradient(120% 110% at 100% 0, color-mix(in srgb, var(--light) 15%, transparent), transparent 62%), var(--pane-edge), var(--surface);
  box-shadow: inset 0 0 0 1px var(--light-line), var(--depth-1), 0 0 36px -20px var(--light-glow);
}
[dir='rtl'] .bk-soon { background: radial-gradient(120% 110% at 0 0, color-mix(in srgb, var(--light) 15%, transparent), transparent 62%), var(--pane-edge), var(--surface); }
.bk-soon.loading { padding: 0; background: none; box-shadow: none; }
.bk-soon-skel { width: 100%; height: 132px; border-radius: 22px; }
.bk-soon-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 28px; }
.bk-soon-top .eyebrow { display: inline-flex; align-items: center; gap: 8px; color: var(--light-hi); font-weight: 600; white-space: nowrap; }
.bk-soon-top .dot { width: 6px; height: 6px; }
.bk-soon-who { display: inline-flex; align-items: center; gap: 8px; min-width: 0; font-size: 13px; color: var(--text-2); }
.bk-soon-who > span:last-child { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.bk-soon-who > .avatar { width: 28px; height: 28px; font-size: 11px; }
.bk-soon-who .avatar-stack .avatar { width: 24px; height: 24px; border-color: var(--surface); }
.bk-soon-t { margin-top: 8px; gap: .16em; text-shadow: 0 0 22px var(--light-glow); }
.bk-soon-t > .icon { align-self: center; width: .5em; height: .5em; margin-inline-start: .12em; color: var(--light); }
.bk-soon-day { margin-top: 4px; font-size: 14px; color: var(--text-2); }
.bk-soon .btn { justify-self: stretch; margin-top: 14px; }
.bk-soon.chosen .bk-soon-top .dot { background: var(--light); box-shadow: 0 0 0 4px var(--light-wash); }
.bk-soon-t.picked { scale: 1; }
/* "Or another time", between the soonest and the days. */
.bk-or { display: flex; align-items: center; gap: 12px; margin: 18px 2px 12px; font-size: 12.5px; line-height: 1.6; color: var(--text-3); white-space: nowrap; }
.bk-or::before, .bk-or::after { content: ''; flex: 1; height: 1px; margin-top: 3px; background: linear-gradient(90deg, transparent, var(--line-2)); }
.bk-or::after { background: linear-gradient(90deg, var(--line-2), transparent); }
.slot-skel { height: 44px; border-radius: 14px; }
.book-sheet .slot-head { position: sticky; top: calc(var(--days-h, 0px) - 4px); z-index: 1; margin: 0 -20px 6px; padding: 6px 22px; background: var(--bg-2); }
@media (min-width: 700px) {
  .book-sheet .day-strip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); overflow: visible; margin-inline: 0; padding-inline: 0; -webkit-mask-image: none; mask-image: none; }
  .book-sheet .day-chip { min-width: 0; }
  .bk-days { position: static; margin: 0; padding: 0 0 4px; background: none; }
  .book-sheet .slot-head { top: -4px; }
}

.slot-group + .slot-group { margin-top: 18px; }
.slot-group .eyebrow { margin: 0 2px 8px; }
.slot-head { display: flex; align-items: center; gap: 7px; }
.slot-head .icon { width: 17px; height: 17px; color: var(--brand); }
.slot-head > span:first-of-type { color: var(--text-2); font-weight: 600; }
.slot-count { display: inline-grid; place-items: center; min-width: 22px; height: 19px; padding: 0 6px; border-radius: 99px; background: var(--surface-2); color: var(--text-3); font-size: 11px; font-weight: 600; }
/* Just the clock in each (the group's title has the part of the day): five to a row on a phone. */
.slot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 8px; }
.slot { height: 44px; padding: 0 6px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line); font-weight: 600; font-size: 15px; white-space: nowrap; cursor: pointer; animation: rise .45s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 25ms); transition: background-color .2s, border-color .2s, transform .25s var(--spring), color .2s; }
.slot b { font-weight: 600; }
.slot:hover { border-color: var(--brand-line); }
.slot:active { transform: scale(.94); }
.slot.on { background: var(--grad, var(--brand)); color: var(--on-brand); border-color: transparent; box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), 0 0 0 1px var(--light-line), 0 0 16px -6px var(--light-glow), 0 10px 24px -12px var(--brand-glow); }

/* Step 4 and the booking's page: the booking as a ticket, a perforation between when
   and what. The notches are cut out with masks, so the page shows through. */
.bk-details .bk-fields, .cliq-card .bk-fields { margin-top: 12px; }
/* The review: the ticket (each part chosen a way back to its step), who it is for, and
   what happens next. */
.bk-who-h { margin: 24px 2px 10px; font-size: 15px; font-weight: 600; }
.bk-review .bk-who-h + :is(.bk-fields, .bk-me) { margin-top: 0; }
.tk-edit { width: 100%; border: 0; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer; }
.tk-when.tk-edit { position: relative; flex: 1; display: block; padding: 0; border-radius: 12px; }
.tk-when .tk-chg { position: absolute; top: -2px; inset-inline-end: -4px; }
.tk-chg { flex: none; display: inline-flex; align-items: center; gap: 2px; height: 26px; margin-inline-start: auto; padding-inline: 10px 6px; border-radius: 99px; background: var(--light-wash); box-shadow: inset 0 0 0 1px var(--light-line); color: var(--light-hi); font-size: 12px; font-weight: 600; white-space: nowrap; transition: background-color .2s, transform .2s var(--spring); }
.tk-chg .icon { width: 13px; height: 13px; }
@media (hover: hover) { .tk-edit:hover .tk-chg { background: color-mix(in srgb, var(--light) 18%, transparent); } }
.tk-edit:active .tk-chg { transform: scale(.94); }
.tk-row .avatar-stack { flex: none; }
.tk-row .avatar-stack .avatar { width: 30px; height: 30px; border-color: var(--surface); }
.tk-row .avatar-stack .avatar + .avatar { margin-inline-start: -12px; }
/* What happens after the tap, as a short line of lit steps: the words the booking's page uses. */
.bk-next { display: grid; gap: 10px; margin: 0; padding: 14px 16px; list-style: none; border-radius: 18px; background: var(--pane-edge), var(--surface); box-shadow: inset 0 0 0 1px var(--line); }
.bk-next li { position: relative; display: flex; align-items: flex-start; gap: 12px; font-size: 13.5px; line-height: 1.5; color: var(--text-2); }
.bk-next li > span:last-child { padding-top: 4px; }
.bk-next li:not(:last-child)::after { content: ''; position: absolute; top: 31px; bottom: -9px; inset-inline-start: 13.5px; width: 1px; background: linear-gradient(var(--light-line), var(--line)); }
.bk-next-ic { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--brand-soft); color: var(--light); box-shadow: inset 0 0 0 1px var(--light-line); }
.bk-next-ic .icon { width: 15px; height: 15px; }
.bk-review .consent { margin-top: 16px; }
/* Booked here before: "booking as" the name and number known (the number partly hidden),
   with a way to change them, or to say it is someone else on this phone. */
.bk-me { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r); background: var(--surface); border: 1px solid var(--line); }
.bk-me .tk-ic { width: 38px; height: 38px; border-radius: 12px; }
.bk-me-n { font-weight: 600; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bk-me-p { display: block; width: fit-content; color: var(--text-2); font-size: 13px; letter-spacing: .04em; }
.bk-me-acts { flex: none; display: grid; justify-items: end; }
.bk-me-acts .link-btn { padding-block: 3px; font-size: 13.5px; }
.bk-me-acts .not-you { color: var(--text-2); font-weight: 500; }
/* Nothing free for two weeks: the salon's WhatsApp and phone instead of a dead end. */
.bk-none { display: grid; justify-items: center; gap: 12px; margin-top: 8px; padding: 26px 18px 20px; text-align: center; }
.bk-none p { max-width: 300px; color: var(--text-2); font-size: 14.5px; line-height: 1.6; }
.bk-none-acts { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; width: 100%; max-width: 320px; margin-top: 4px; }
.bk-none-acts .btn { padding-inline: 12px; }
.ticket { --cut: 11px; position: relative; filter: drop-shadow(0 18px 28px rgb(0 0 0 / .28)); }
.tk-top, .tk-body { position: relative; background: linear-gradient(165deg, color-mix(in srgb, var(--text) 6%, transparent), transparent 55%), var(--surface); }
.tk-top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px 20px;
  border-radius: var(--r-lg) var(--r-lg) 0 0; box-shadow: inset 0 1px 0 rgb(255 255 255 / .06);
  -webkit-mask: radial-gradient(circle at 0 100%, transparent var(--cut), #000 calc(var(--cut) + .5px)) left / 51% 100% no-repeat, radial-gradient(circle at 100% 100%, transparent var(--cut), #000 calc(var(--cut) + .5px)) right / 51% 100% no-repeat;
  mask: radial-gradient(circle at 0 100%, transparent var(--cut), #000 calc(var(--cut) + .5px)) left / 51% 100% no-repeat, radial-gradient(circle at 100% 100%, transparent var(--cut), #000 calc(var(--cut) + .5px)) right / 51% 100% no-repeat;
}
.tk-body {
  padding: 6px 20px 8px; border-radius: 0 0 var(--r-lg) var(--r-lg); background: var(--surface);
  -webkit-mask: radial-gradient(circle at 0 0, transparent var(--cut), #000 calc(var(--cut) + .5px)) left / 51% 100% no-repeat, radial-gradient(circle at 100% 0, transparent var(--cut), #000 calc(var(--cut) + .5px)) right / 51% 100% no-repeat;
  mask: radial-gradient(circle at 0 0, transparent var(--cut), #000 calc(var(--cut) + .5px)) left / 51% 100% no-repeat, radial-gradient(circle at 100% 0, transparent var(--cut), #000 calc(var(--cut) + .5px)) right / 51% 100% no-repeat;
}
.tk-body::before { content: ''; position: absolute; top: 0; inset-inline: calc(var(--cut) + 8px); border-top: 1.5px dashed var(--line-2); }
.tk-when { min-width: 0; }
.tk-when .eyebrow { color: var(--brand); font-weight: 600; }
.tk-when b { display: block; margin-top: 2px; font-size: 32px; font-weight: var(--w-figure); line-height: 1.2; }
.tk-time { display: inline-flex; align-items: center; gap: 6px; margin-top: 6px; color: var(--text-2); font-size: 14.5px; }
.tk-time .icon { width: 16px; height: 16px; color: var(--brand); }
.tk-note { display: flex; align-items: center; gap: 6px; width: fit-content; margin-top: 10px; padding: 4px 11px; border-radius: 14px; background: var(--brand-soft); font-size: 12.5px; }
.tk-note .icon { width: 15px; height: 15px; color: var(--brand); }
.tk-no { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.tk-no .eyebrow { font-size: 11px; }
.tk-no .pill { height: 26px; color: var(--text); font-weight: 600; }
.tk-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; font-size: 14.5px; }
.tk-row + .tk-row { border-top: 1px solid var(--line); }
.tk-ic { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 13px; background: var(--surface-2); color: var(--text-2); }
.tk-ic.svc { color: var(--brand); }
.tk-ic.svc .icon { width: 20px; height: 20px; }
.tk-ic .icon { width: 18px; height: 18px; }
.tk-row .avatar { width: 40px; height: 40px; }
.tk-n { font-weight: 600; font-size: 15.5px; }
.tk-s { font-size: 12.5px; color: var(--text-2); }
.tk-price { display: flex; align-items: baseline; gap: 5px; color: var(--brand); font-size: 17px; white-space: nowrap; }
.tk-price small { color: var(--text-2); font-size: 11.5px; font-weight: 500; }
/* Where the money stands: a short receipt under the visit (paid by CliQ, left for the salon). */
.tk-money { padding: 8px 0; font-size: 14px; color: var(--text-2); }
.tk-row:not(.tk-money) + .tk-money { padding-top: 14px; }
.tk-money + .tk-money { border-top: 0; }
.tk-money:last-child { padding-bottom: 12px; }
.tk-money .tk-ic { height: 24px; background: none; color: var(--text-3); }
.tk-money b { display: flex; align-items: baseline; gap: 5px; color: var(--text); font-size: 15px; font-weight: 600; white-space: nowrap; }
.tk-money b small { color: var(--text-2); font-size: 11.5px; font-weight: 500; }
.tk-money.now .tk-ic, .tk-money.now b, .tk-money.sent .tk-ic { color: var(--brand); }
.tk-money.paid .tk-ic { color: var(--ok); }
/* A booking that is off: faded, its time struck through. */
[data-page='day'] .ticket { filter: drop-shadow(0 12px 24px rgb(0 0 0 / .1)); }
.ticket.void { opacity: .62; filter: none; }
.ticket.void .tk-when b, .ticket.void .tk-time { text-decoration: line-through; text-decoration-color: var(--text-3); text-decoration-thickness: 1.5px; }
.ticket.void .tk-when .eyebrow { color: var(--text-3); }
.notice { display: flex; gap: 10px; align-items: flex-start; margin-top: 16px; padding: 12px 14px; border-radius: 14px; background: var(--brand-soft); border: 1px solid var(--brand-line); font-size: 13.5px; line-height: 1.5; }
.notice .icon { width: 18px; height: 18px; margin-top: 2px; color: var(--brand); }


/* The booking's page: the salon's night with a glow from above, tinted by how the
   booking stands (the salon's light while it waits and once its pole is lit, red when it
   fell through). */
.booking-page {
  --bk-glow: var(--brand); min-height: 100dvh;
  background: radial-gradient(95% 440px at 50% 0, color-mix(in srgb, var(--bk-glow) 17%, transparent), transparent 75%), var(--bg);
}
.booking-page[data-kind='ok'] { --bk-glow: var(--light); }
.booking-page[data-kind='bad'] { --bk-glow: color-mix(in srgb, var(--danger) 70%, transparent); }
.booking-page[data-kind='off'] { --bk-glow: var(--text-3); }
.booking-top { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 10px; padding: calc(10px + var(--safe-top)) 16px 10px; background: var(--glass); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border-bottom: 1px solid var(--line); font-weight: 600; }
.booking-top .app-icon { --s: 32px; border-radius: 10px; }
/* .page (further down) sets the same properties: these carry its class to win. */
.page.bk-main { max-width: 600px; }
.page.bk-fail { padding-top: 14vh; }
.status-hero { text-align: center; padding: 22px 8px 4px; }
.status-hero h1 { font-size: 27px; margin-top: 20px; }
.status-hero p { max-width: 440px; margin: 6px auto 0; color: var(--text-2); }
.status-icon { position: relative; width: 88px; height: 88px; margin: 0 auto; border-radius: 50%; display: grid; place-items: center; animation: pop .6s var(--spring); }
.status-icon > .icon { width: 40px; height: 40px; stroke-width: 2.2; }
/* A booking that stands (held, waiting on the salon, confirmed) is shown by the barber's
   pole: half lit with a brass lock while the time is held, half lit and turning while the
   salon checks, lit with a brass check once confirmed. */
.status-icon.has-pole { width: 112px; height: 112px; }
.status-icon.off { background: var(--surface-2); color: var(--text-3); }
.status-icon.off.bad { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); box-shadow: 0 0 0 10px color-mix(in srgb, var(--danger) 7%, transparent); }
/* While the deposit is under way: a small icon beside the title, no halo, so the task
   (the alias and the upload, or the screenshot sent) is on the first screen. */
.status-hero.compact { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 14px; padding: 6px 2px 0; text-align: start; }
.status-hero.compact .status-icon { width: 48px; height: 48px; margin: 0; box-shadow: none; }
.status-hero.compact .status-icon > .icon { width: 24px; height: 24px; }
/* The pole in the small tile: half size, a smaller coin on the tile's corner, no glint. */
.status-hero.compact .ps-halo { inset: -18%; }
.status-hero.compact .ps-glint { display: none; }
.status-hero.compact .ps-pole { scale: .5; margin-top: -37px; }
.status-hero.compact .ps-coin { inset-inline-end: -5px; bottom: -5px; width: 21px; height: 21px; }
.status-hero.compact .ps-coin .icon { width: 11px; height: 11px; stroke-width: 3; }
.status-hero.compact h1 { margin: 0; font-size: clamp(19px, 5.5vw, 22px); line-height: 1.3; }
.status-hero.compact p { max-width: none; margin: 2px 0 0; font-size: 14px; }
.status-hero.compact .bk-offline { grid-column: 1 / -1; justify-self: start; margin-top: 12px; }
/* A change seen live: the words cross-fade, only the timeline moves. The title takes the
   focus then (its button is gone), without a ring: it is not something to press. */
.status-hero.swap > h1, .status-hero.swap > p { animation: fade .25s ease both; }
.status-hero h1:focus { outline: none; }
@keyframes ping { from { transform: scale(1); opacity: .7; } to { transform: scale(1.6); opacity: 0; } }
/* "This page updates by itself", with a live dot; a quiet note while polls fail. */
.live-pill { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; padding: 6px 13px; border-radius: 99px; background: var(--surface); border: 1px solid var(--line); color: var(--text-2); font-size: 12.5px; }
.live-pill i { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--ok); }
.live-pill i::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--ok); animation: ping 1.6s var(--ease-out) infinite; }
.bk-offline { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 10px; color: var(--warn); font-size: 12.5px; }
.bk-offline .spinner { width: 14px; height: 14px; border-width: 2px; }
/* The pole at 128px on wide screens; the only one with a name, so a live change can morph it. */
@media (min-width: 700px) {
  .status-hero:not(.compact) .status-icon.has-pole { width: 128px; height: 128px; }
  .status-hero:not(.compact) .ps-pole { scale: 1.12; }
}
.status-hero .bk-pole { view-transition-name: bk-pole; }
::view-transition-group(bk-pole) { animation-duration: .5s; animation-timing-function: var(--ease-out); }
:root.vt-pole::view-transition-old(root) { animation: vt-out .25s ease both; }
:root.vt-pole::view-transition-new(root) { animation: fade .25s ease both; }

/* The salon confirms (booking.js playMoment): the page is drawn with the pole still half
   lit, its words and the ticket held back (data-moment=ready); then the pole switches on,
   the words rise under it and the ticket issues from beneath, a gloss crossing it once.
   It reads as booked at about 1s and has settled by 2.3s (data-moment=done). */
.booking-page[data-moment='ready'] .status-hero .bk-pole { --lit: .45; }
.booking-page[data-moment='ready'] :is(.status-hero .ps-coin, .status-hero > h1, .status-hero > p, .bk-main > .ticket) { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .status-hero.lighting > h1 { animation: rise .6s var(--ease-out) .3s both; }
  .status-hero.lighting > p { animation: rise .6s var(--ease-out) .38s both; }
  .booking-page.issuing .bk-main > .ticket { animation: bk-issue .65s var(--spring) 1s both; }
  .booking-page.issuing .bk-main > .ticket .tk-top::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; translate: -100% 0;
    background: linear-gradient(100deg, transparent 30%, rgb(255 255 255 / .1) 46%, color-mix(in srgb, var(--light) 22%, transparent) 50%, transparent 64%);
    animation: bk-gloss .9s var(--ease-sweep) 1.35s both;
  }
  [dir='rtl'] .booking-page.issuing .bk-main > .ticket .tk-top::after { translate: 100% 0; animation-name: bk-gloss-rtl; }
  :root[data-motion='lite'] .booking-page.issuing .bk-main > .ticket .tk-top::after { display: none; }
}
@keyframes bk-issue { from { opacity: 0; translate: 0 -24px; scale: .97; } }
@keyframes bk-gloss { from { translate: -100% 0; } to { translate: 100% 0; } }
@keyframes bk-gloss-rtl { from { translate: 100% 0; } to { translate: -100% 0; } }

/* «تم الحجز», right after booking (booking.js playBeat): over the page drawn beneath, the
   pole switches on and turns, the steel shears snip the ticket along its perforation (the
   cut lights up), a few clippings fall and the words light up like a sign; then the pole
   flies to its place in the page's heading and the ticket to its own. 2.2s; 1.5s and no
   clippings in lite; never at reduced motion. */
.booking-page[data-beat] :is(.status-hero .status-icon, .bk-main > .ticket) { animation: none; opacity: 0; }
.booking-page[data-beat] .status-hero > :not(.status-icon) { transition: opacity .35s ease; }
.booking-page[data-beat='playing'] .status-hero > :not(.status-icon) { opacity: 0; }
.booking-page.landed .status-hero .status-icon { animation: none; }
.bk-beat { position: fixed; inset: 0; z-index: 150; display: grid; place-items: center; padding: 16px; pointer-events: none; --shw: 150px; --x-dir: 1; }
@media (min-width: 700px) { .bk-beat { --shw: 176px; } }
[dir='ltr'] .bk-beat { --x-dir: -1; }
.bk-beat.gone { opacity: 0; transition: opacity .16s ease; }
.bb-dim {
  position: absolute; inset: 0;
  background: radial-gradient(60% 44% at 50% 36%, color-mix(in srgb, var(--light) 14%, transparent), transparent 72%), color-mix(in srgb, var(--bg) 97%, transparent);
  animation: fade .24s ease both;
}
.bb-stage { position: relative; display: flex; flex-direction: column; align-items: center; width: min(var(--tw, 568px), 100%); }
.bb-seal { position: relative; width: 112px; height: 112px; }
.bb-word {
  margin: 16px 0 20px; font-size: 30px; font-weight: 700; line-height: 1.2; color: var(--text);
  text-shadow: 0 0 2px var(--light-hi), 0 0 16px var(--light-glow), 0 0 34px color-mix(in srgb, var(--light) 35%, transparent);
  animation: bb-word .5s linear 1.1s both;
}
@keyframes bb-word { 0% { opacity: 0; } 24% { opacity: .75; } 40% { opacity: .25; } 70%, 100% { opacity: 1; } }
.bb-ticket { position: relative; width: 100%; animation: bb-rise .45s var(--ease-out) .12s both; }
@keyframes bb-rise { from { opacity: 0; translate: 0 28px; } }
.bb-ticket .ticket { filter: drop-shadow(0 26px 44px rgb(0 0 0 / .55)); }
/* The cut along the perforation, lit from the inline end where the shears are. */
.bb-cut {
  position: absolute; top: calc(var(--perf, 120px) - 1px); inset-inline: 15px; height: 2px; border-radius: 2px; scale: 0 1; transform-origin: left;
  background: linear-gradient(90deg, transparent, var(--light-hi) 12%, #fff 50%, var(--light-hi) 88%, transparent); box-shadow: 0 0 10px 1px var(--light-glow);
}
[dir='ltr'] .bb-cut { transform-origin: right; }
/* By day light does not glow: the cut is drawn in the accent's ink. */
[data-page='day'] .bb-cut { background: linear-gradient(90deg, transparent, var(--light) 8%, var(--light) 92%, transparent); box-shadow: none; }
.bk-beat.cut .bb-cut { animation: bb-cut .45s var(--ease-out) forwards; }
@keyframes bb-cut { to { scale: 1 1; } }
/* The shears: tips on the perforation, the finger rings just past the ticket's edge. */
.bb-tips { position: absolute; top: var(--perf, 120px); inset-inline-end: calc(var(--shw) * .977 - 12px); width: 0; height: 0; }
.bb-shears {
  left: calc(var(--shw) * -.977); top: calc(var(--shw) * -48 / 260); width: var(--shw); aspect-ratio: 260 / 96;
  transform-origin: 97.7% 50%; scale: var(--x-dir) 1; rotate: calc(var(--x-dir) * 7deg);
  animation: bb-sh-in .4s var(--ease-out) .45s both, bb-sh-out .3s ease-in 1.5s forwards;
}
@keyframes bb-sh-in { from { opacity: 0; translate: calc(var(--x-dir) * -36px) -48px; rotate: calc(var(--x-dir) * 30deg); } }
@keyframes bb-sh-out { to { opacity: 0; translate: calc(var(--x-dir) * -30px) -40px; rotate: calc(var(--x-dir) * 22deg); } }
/* The pole here: its coin comes with the words; held, the whirl settles and stops. */
.bk-beat .bk-pole.moment .ps-coin { animation-delay: 1.2s; }
.bk-beat .bk-pole.moment .ps-coin.c-check .icon > * { animation-delay: 1.35s; }
.bk-beat.held .bk-pole.moment .ps-stripes { animation: ps-whirl 1.2s cubic-bezier(.55, 0, .25, 1) .3s both; }
.bk-beat.leave .bb-word { animation: bb-out .18s ease forwards; }
.bk-beat.leave .bb-dim { animation: bb-out .36s ease .1s forwards; }
@keyframes bb-out { to { opacity: 0; } }
/* Lite: a plain switch-on, one snip, no clippings; 1.5s. */
.bk-beat[data-level='lite'] .bk-pole.moment .ps-halo { animation: ps-on .3s ease-out .1s both; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-veil { animation: ps-off .3s ease-out .1s both; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-light { animation: ps-fill .3s var(--ease-out) .1s both; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-stripes { animation: ps-turn 2.6s linear .2s 1; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-glint::before { animation: none; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-coin { animation-delay: .8s; }
.bk-beat[data-level='lite'] .bk-pole.moment .ps-coin.c-check .icon > * { animation-delay: .95s; }
.bk-beat[data-level='lite'] .bb-shears { animation: bb-sh-in .3s var(--ease-out) .25s both, bb-sh-out .25s ease-in .95s forwards; }
.bk-beat[data-level='lite'] .bb-word { animation: fade .3s ease .72s both; }

/* The hand-off from the booking sheet (booking.js handoff): the sheet gives way and the
   new page rises while the review's ticket glides to where the page shows it (under
   «تم الحجز»'s shears, or its place on the page). Full motion only. */
html[data-vt='ticket']::view-transition-old(root) { animation: fade .2s ease reverse both; }
html[data-vt='ticket']::view-transition-new(root) { animation: rise .45s var(--ease-out) both; }
::view-transition-group(bk-ticket) { animation-duration: .5s; animation-timing-function: var(--ease-out); }
/* The two tickets are not the same size: the review's gives way quickly and the new one
   comes in behind it, so their words never sit doubled. */
::view-transition-old(bk-ticket) { animation: fade .2s ease reverse both; }
::view-transition-new(bk-ticket) { animation: fade .3s ease .12s both; }
/* The beat's ticket came in from the sheet: no rise of its own. */
.bk-beat.handed .bb-ticket { animation: none; }
/* With a deposit to send, the beat's ticket files itself into the booking's line at the
   top of the timeline, which lights as it lands. */
.booking-page[data-beat] .bk-journey .jn-sum { opacity: 0; }
.booking-page.landed .bk-journey .jn-sum { animation: jn-filed .7s var(--ease-out); }
@keyframes jn-filed { 30% { box-shadow: inset 0 0 0 1px var(--light), 0 0 0 5px var(--light-wash), 0 0 20px -2px var(--light-glow); } }

/* The booking's timeline: a node per step on a spine, lit when done, ringed when it is
   the step now (with what to do in it), dimmed on a dashed spine when still to come. A
   step that did not happen is a failed node and the road after it is struck through.
   While the customer waits on the salon, the spine into that step turns like a pole. */
.bk-journey { list-style: none; margin-inline: 0; margin-bottom: 0; padding: 0; display: grid; gap: 16px; }
.jn { position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: 14px; align-items: start; }
.jn::before {
  content: ''; position: absolute; inset-inline-start: 13px; top: 32px; bottom: -14px; width: 2px; border-radius: 2px;
  background: repeating-linear-gradient(180deg, var(--line-2) 0 5px, transparent 5px 10px);
}
.jn:last-child::before { display: none; }
.jn[data-state='done']::before { background: var(--light); box-shadow: 0 0 8px -1px var(--light-glow); }
.jn[data-state='fail']::before, .jn.struck::before { background: repeating-linear-gradient(180deg, var(--line) 0 2px, transparent 2px 6px); box-shadow: none; }
.jn-node { --sn: 28px; position: relative; z-index: 1; }
.jn-node > i { width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); }
.jn-body { min-width: 0; padding-top: 2px; }
.jn-t { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.5; }
.jn-s { margin-top: 1px; color: var(--text-2); font-size: 13.5px; line-height: 1.55; }
.jn[data-state='next'] > .jn-node, .jn[data-state='next'] .jn-t { opacity: .6; }
/* Its line (the visit's own date and time) stays readable: text-2 is already the quieter voice. */
.jn[data-state='next'] .jn-t { font-weight: 500; }
.jn.struck { opacity: .4; }
.jn.struck > .jn-node, .jn.struck .jn-t, .jn.struck .jn-s { opacity: 1; }
.jn.struck .jn-t { text-decoration: line-through; text-decoration-color: var(--text-3); text-decoration-thickness: 1.5px; }
/* The spine into the step where he waits: a thin glass tube with the pole's stripes
   moving down into it (full motion; still otherwise). */
.jn-spine { position: absolute; z-index: 1; inset-inline-start: 12px; top: 32px; bottom: -14px; width: 4px; border-radius: 99px; overflow: hidden; overflow: clip; box-shadow: 0 0 10px -1px var(--light-glow); }
.jn-spine::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgb(255 255 255 / .4), transparent 55%, rgb(0 0 0 / .3)); }
[data-theme='public'][data-page='day'] .jn-spine::after { box-shadow: inset 0 0 0 1px rgb(20 18 16 / .22); border-radius: inherit; }
.pole-stripes.v { inset-block: -40px 0; inset-inline: 0; background: repeating-linear-gradient(150deg, var(--pole-red) 0 7px, var(--pole-white) 7px 14px, var(--pole-blue) 14px 21px, var(--pole-white) 21px 28px); }
[dir='rtl'] .pole-stripes.v { background: repeating-linear-gradient(210deg, var(--pole-red) 0 7px, var(--pole-white) 7px 14px, var(--pole-blue) 14px 21px, var(--pole-white) 21px 28px); }
:root[data-motion='full'] .pole-stripes.v, :root[data-motion='full'][dir='rtl'] .pole-stripes.v { animation-name: pole-stripe-v; }
/* 28px across the stripes is 32.33px down the tube (28 / sin 60deg): a seamless loop. */
@keyframes pole-stripe-v { to { translate: 0 32.33px; } }
.jn .live-pill { margin-top: 10px; }
.jn .cliq-card { margin-top: 10px; }
/* The booking in one line: the service's glyph, its name, when, its number. */
.jn-sum { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; height: 34px; margin-top: 8px; padding-inline: 4px 13px; border-radius: 99px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2); font-size: 13px; white-space: nowrap; }
.jn-sum-ic { flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--light-wash); box-shadow: inset 0 0 0 1px var(--light-line); color: var(--light); }
.jn-sum-ic .icon { width: 14px; height: 14px; }
.jn-sum-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text); font-weight: 600; }
.jn-sum-w, .jn-sum-no { flex: none; }
.jn-sum-w::before, .jn-sum-no::before { content: '·'; margin-inline-end: 8px; color: var(--text-3); }
.jn-sum-no { color: var(--text-3); }
/* The day of the visit: how far off it is, a tip, the calendar; then the way there. */
.jn-when { display: inline-flex; align-items: center; gap: 7px; height: 30px; margin-top: 6px; padding: 0 13px 0 11px; border-radius: 99px; background: var(--light-wash); box-shadow: inset 0 0 0 1px var(--light-line), 0 0 16px -8px var(--light-glow); color: var(--light-hi); font-size: 13.5px; font-weight: 600; }
.jn-when .icon { flex: none; width: 15px; height: 15px; }
.jn-tip { display: flex; align-items: center; gap: 8px; margin-top: 10px; color: var(--text-2); font-size: 13.5px; line-height: 1.5; }
.jn-tip .icon { flex: none; width: 16px; height: 16px; color: var(--light); }
.jn-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.jn-acts.stack { display: grid; gap: 10px; }
.jn-acts .btn-sm .icon { width: 17px; height: 17px; }
/* What led to a booking, folded under its lit step. */
.jn-fold { margin-top: 4px; }
.jn-fold summary { display: inline-flex; align-items: center; gap: 6px; padding: 4px 0; color: var(--text-2); font-size: 12.5px; cursor: pointer; list-style: none; }
.jn-fold summary::-webkit-details-marker { display: none; }
.jn-fold summary:hover { color: var(--text); }
.jn-fold-ic { width: 14px; height: 14px; transition: rotate .25s var(--ease-out); }
.jn-fold[open] .jn-fold-ic { rotate: 180deg; }
.jn-past { list-style: none; margin: 6px 0 2px; padding: 0; display: grid; gap: 7px; }
.jn-past li { display: flex; align-items: center; gap: 9px; color: var(--text-2); font-size: 13px; line-height: 1.45; }
.jn-past-ic { flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--light-wash); color: var(--light); }
.jn-past-ic .icon { width: 11px; height: 11px; stroke-width: 3; }
/* A status seen changing: the step just done draws its check and fills its spine; the
   step now gets its ring (and the ping every step now has once). */
.jn.just > .jn-node { animation: pop .4s var(--spring); }
.jn.just[data-state='done'] > .jn-node .icon > * { stroke-dasharray: 24; stroke-dashoffset: 24; animation: draw .4s var(--ease-out) .12s forwards; }
.jn.just::before, .jn.just > .jn-spine { transform-origin: top; animation: jn-draw .4s var(--ease-out) .1s both; }
.jn.arrive > .jn-node { animation: pop .45s var(--spring) .25s both; }
/* A confirmed visit's timeline draws itself in after the pole's moment: the spine grows
   down, the nodes pop in 90ms apart. */
.bk-journey.await > .jn { opacity: 0; }
.bk-journey.drawing > .jn { animation: jn-in .5s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 90ms); }
.bk-journey.drawing > .jn > .jn-node { animation: pop .4s var(--spring) both; animation-delay: calc(var(--i, 0) * 90ms); }
.bk-journey.drawing > .jn::before { transform-origin: top; animation: jn-draw .6s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 90ms + 120ms); }
@keyframes jn-in { from { opacity: 0; translate: 0 10px; } }
@keyframes jn-draw { from { scale: 1 0; } }

/* The booking's ticket is this screen's mirror: the neon rim round both its parts (broken
   at the notches) and the light's wash from above; the glass streaks stay off a ticket. */
.ticket.mirror { overflow: visible; isolation: auto; border: 0; background: none; box-shadow: none; filter: drop-shadow(0 18px 28px rgb(0 0 0 / .28)) drop-shadow(0 0 24px color-mix(in srgb, var(--light) 12%, transparent)); }
.ticket.mirror::before, .ticket.mirror::after { content: none; }
.ticket.mirror .tk-top { border: 1.5px solid transparent; border-bottom: 0; background: radial-gradient(120% 100% at 50% -30%, var(--light-wash), transparent 62%) padding-box, linear-gradient(165deg, color-mix(in srgb, var(--text) 6%, transparent), transparent 55%) padding-box, linear-gradient(var(--surface), var(--surface)) padding-box, var(--mirror-rim, var(--rim)) border-box; }
.ticket.mirror .tk-body { border: 1.5px solid transparent; border-top: 0; background: linear-gradient(var(--surface), var(--surface)) padding-box, var(--mirror-rim, var(--rim)) border-box; }
[data-page='day'] .ticket.mirror { filter: drop-shadow(0 12px 24px rgb(0 0 0 / .1)); }
.bb-ticket .ticket.mirror { filter: drop-shadow(0 26px 44px rgb(0 0 0 / .55)) drop-shadow(0 0 24px color-mix(in srgb, var(--light) 14%, transparent)); }

/* On a wide screen: the timeline on the start side, the ticket beside it, sticky. */
@media (min-width: 900px) {
  .page.bk-main.split { max-width: 960px; display: grid; grid-template-columns: minmax(0, 1fr) 380px; grid-auto-flow: row dense; align-items: start; column-gap: 32px; row-gap: 24px; }
  .page.bk-main.split > * { grid-column: 1 / -1; margin-top: 0; }
  .page.bk-main.split > .bk-journey { grid-column: 1; }
  .page.bk-main.split > .ticket { grid-column: 2; position: sticky; top: 84px; }
  .page.bk-main.split > .center-link { margin-top: 4px; }
}

/* The deposit: amount and the hold's ring, then the steps as a numbered timeline. */
.cliq-card { border-color: var(--brand-line); }
.booking-page .cliq-card { background: radial-gradient(120% 60% at 100% 0, color-mix(in srgb, var(--brand) 11%, transparent), transparent 60%), var(--surface); }
[dir='rtl'] .booking-page .cliq-card { background: radial-gradient(120% 60% at 0 0, color-mix(in srgb, var(--brand) 11%, transparent), transparent 60%), var(--surface); }
.cliq-card .amount { font-size: 34px; font-weight: var(--w-figure); line-height: 1.2; font-variant-numeric: tabular-nums; }
.cliq-card .timer { text-align: end; }
.cliq-card .timer b { display: block; font-size: 22px; color: var(--brand); }
.cliq-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cliq-amount { display: flex; align-items: center; gap: 8px; }
.amt-copy { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text-2); cursor: pointer; transition: background-color .25s, color .25s, border-color .25s; }
.amt-copy:hover { color: var(--text); border-color: var(--brand-line); }
.amt-copy .icon { width: 15px; height: 15px; }
.amt-copy.copied { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.cliq-clock { display: flex; align-items: center; gap: 10px; }
.cliq-clock .lbl { max-width: 96px; color: var(--text-2); font-size: 12px; line-height: 1.45; text-align: end; }
.cliq-ring { position: relative; flex: none; display: grid; place-items: center; width: 68px; height: 68px; }
.cliq-ring svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.cliq-ring circle { fill: none; stroke-width: 4.5; }
.cliq-ring .track { stroke: var(--line-2); }
.cliq-ring .value { stroke: var(--brand); stroke-linecap: round; filter: drop-shadow(0 0 5px var(--brand-glow)); transition: stroke-dashoffset 1s linear, stroke .3s; }
.cliq-ring b { position: relative; color: var(--brand); font-size: 15px; font-weight: 700; }
/* The last five minutes: amber, and a slow pulse. */
.cliq-clock.low .value { stroke: var(--warn); filter: drop-shadow(0 0 6px color-mix(in srgb, var(--warn) 60%, transparent)); }
.cliq-clock.low b { color: var(--warn); }
.cliq-clock.low .cliq-ring { animation: hold-pulse 1.6s ease-in-out infinite; }
@keyframes hold-pulse { 50% { transform: scale(1.07); } }
/* CliQ in four steps: copy the alias, pay in the bank app (the taps it takes, as a path),
   attach the screenshot, send it. The step now is ringed; the rest wait at 70%, none locked. */
.cliq-flow { list-style: none; counter-reset: cliq; margin: 18px 0 14px; padding: 0; display: grid; gap: 16px; font-size: 14.5px; }
.cf-step { position: relative; counter-increment: cliq; min-height: 26px; padding-inline-start: 38px; line-height: 1.6; transition: opacity .3s; }
.cf-step::before { content: counter(cliq); position: absolute; top: -1px; inset-inline-start: 0; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand-line); font-size: 13px; font-weight: 700; line-height: 1; transition: box-shadow .3s; }
.cf-step:not(:last-child)::after { content: ''; position: absolute; top: 29px; bottom: -14px; inset-inline-start: 12.5px; width: 1px; background: var(--line-2); }
.cf-step[data-state='done']:not(:last-child)::after { background: var(--brand-line); }
.cf-step[data-state='now']::before { box-shadow: inset 0 0 0 1.5px var(--brand), 0 0 0 4px var(--brand-soft); }
.cf-step:not([data-state='now']) { opacity: .7; }
.cf-step:focus-within, .cf-step:hover { opacity: 1; }
.cf-step .step-check { position: absolute; top: -1px; inset-inline-start: 0; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--grad, var(--brand)); color: var(--on-brand); animation: pop .35s var(--spring); }
.cf-step .step-check .icon { width: 15px; height: 15px; stroke-width: 2.6; }
.cf-t { display: block; font-weight: 600; }
.cf-sub { margin-top: 2px; font-size: 12.5px; line-height: 1.5; color: var(--text-2); }
.cf-path { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 4px; margin-top: 6px; }
.cf-pill { display: inline-flex; align-items: center; height: 26px; padding: 0 10px; border-radius: 99px; background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 12.5px; line-height: 1; color: var(--text); white-space: nowrap; }
.cf-pill.amt { background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand-line); color: var(--text); font-weight: 600; }
.cf-chev { flex: none; width: 13px; height: 13px; color: var(--text-3); }
.cf-step .proof-drop { margin-top: 8px; }
.cf-hint { display: flex; align-items: center; gap: 6px; margin-top: 8px; color: var(--brand); font-size: 12.5px; font-weight: 600; line-height: 1.45; }
.cf-hint .icon { flex: none; width: 15px; height: 15px; }
/* Back from the bank with nothing attached: the drop pulses once. */
.proof-drop.nudge { animation: cf-nudge .6s var(--ease-out); }
@keyframes cf-nudge { 35% { box-shadow: 0 0 0 6px var(--brand-soft), 0 0 22px -4px var(--brand-glow); border-color: var(--brand); } }
.cf-after { margin: 0; line-height: 1.55; }
.alias { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 8px 0 4px; padding: 8px 8px 8px 14px; border-radius: 14px; background: var(--surface-2); border: 1px dashed var(--brand-line); font-size: 18px; font-weight: 700; letter-spacing: .03em; }
[dir='rtl'] .alias { padding: 8px 14px 8px 8px; }
.alias .icon-btn { width: 38px; height: 38px; border-radius: 11px; }
/* The whole alias row copies; it answers with a check and a green edge. */
button.alias { width: 100%; color: var(--text); font-family: inherit; text-align: start; cursor: pointer; transition: border-color .25s, background-color .25s, transform .25s var(--spring); }
button.alias:hover { border-color: var(--brand); }
button.alias:active { transform: scale(.985); }
.alias .copy-ic { flex: none; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 11px; background: var(--surface-3); color: var(--text-2); transition: background-color .25s, color .25s; }
.alias .copy-ic .icon { width: 18px; height: 18px; }
button.alias:hover .copy-ic { background: var(--brand); color: var(--on-brand); }
.alias.copied, .alias.copied:hover { border-style: solid; border-color: var(--ok); background: color-mix(in srgb, var(--ok) 10%, var(--surface-2)); }
.alias.copied .copy-ic, button.alias.copied:hover .copy-ic { background: var(--ok); color: var(--bg); }
.copied .copy-ic .icon { animation: pop .35s var(--spring); }
.clip-buffer { position: fixed; top: 0; inset-inline-start: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.link-btn.wa { margin-top: 12px; }
/* Cancelling is there, without the weight of a main action. */
.center-link { display: flex; margin: 0 auto; font-size: 14px; }
.stack-lg > .center-link { margin-top: 10px; }
.center-link:hover { text-decoration: underline; text-underline-offset: 4px; }
.center-link.busy { opacity: .5; }
@media (min-width: 900px) {
  .booking-page { background: radial-gradient(60% 560px at 50% 0, color-mix(in srgb, var(--bk-glow) 17%, transparent), transparent 75%), var(--bg); }
  .page.bk-main { padding-top: 36px; }
  .status-hero h1 { font-size: 32px; }
  .status-hero.compact h1 { font-size: 26px; }
}
.details .kv { display: flex; align-items: center; gap: 10px; margin-top: 12px; font-size: 14px; }
.details .kv .icon { width: 18px; height: 18px; color: var(--text-3); }
.details .kv .avatar { width: 26px; height: 26px; font-size: 11px; }
.details .name { font-weight: 600; }

.pill.status-confirmed, .pill.status-completed { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); border-color: transparent; }
.pill.status-pending_payment { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); border-color: transparent; }
.pill.status-payment_sent { color: var(--info); background: color-mix(in srgb, var(--info) 14%, transparent); border-color: transparent; }
.pill.status-no_show { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: transparent; }
.pill.status-cancelled, .pill.status-expired { color: var(--text-3); }

/* ==========================================================================
   Owner schedule
   ========================================================================== */
.icon-btn.primary-icon { background: var(--grad, var(--brand)); border-color: transparent; color: var(--on-brand); box-shadow: inset 0 1px 0 rgb(255 255 255 / .25), 0 0 0 1px var(--light-line), 0 0 16px -6px var(--light-glow), 0 10px 22px -10px var(--brand-glow); }
.icon-btn.primary-icon:hover { filter: brightness(1.08); background: var(--grad, var(--brand)); }
.link-btn.danger-link { color: var(--danger); }
/* The same red as the tab bar's count for the same number. */
.count.hot { margin-inline-start: 8px; background: var(--danger); border-color: transparent; color: var(--bg); }
.day-strip { position: relative; }
/* "Now" takes the studio's own light (the salon's accent in salon colours). */
.sched, .sched-sheet { --now: var(--glow-1-soft, #f472b6); }

/* New booking: beside how booking works, named (the walk-in is the studio's own, in the tab bar). */
.sched .add-btn { flex: none; height: 44px; padding: 0 14px; gap: 7px; border-radius: 14px; }
.sched .add-btn .icon { width: 20px; height: 20px; }
/* Phones: the title and its two buttons on one row (the line under it steps aside, and
   the title gives a little at 360px); a narrower screen drops the buttons under the title
   rather than cutting it. */
@media (max-width: 719px) {
  .sched-head { flex-wrap: wrap; gap: 12px 8px; }
  .sched-head > .grow { min-width: min-content; }
  .sched-head .s-title { font-size: clamp(24px, 6.8vw, 30px); }
  .sched-head .add-btn { padding: 0 12px; }
  .sched-head .s-sub { display: none; }
}

/* Phones: one column, the deposits first (placed there in the DOM by the page).
   Wide screens: see the media query below. */
.sched-cols { display: flex; flex-direction: column; }
.sched-main, .sched-side { display: contents; }
.sched-detail-box, .sched-stats-box { display: none; }

.off-note { align-items: center; margin: 0 0 18px; border-color: var(--line-2); background: var(--surface); }
.off-note .icon { margin: 0; color: var(--text-3); }
.notice.calm { background: color-mix(in srgb, var(--ok) 10%, transparent); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.notice.calm .icon { color: var(--ok); }

/* Deposits waiting on the owner glow a little, the sent ones most. */
.attention { margin-top: 0; margin-bottom: 24px; }
.attention .section-head h2 { display: flex; align-items: center; }
.attention .card { border-color: color-mix(in srgb, var(--info) 30%, var(--line)); background: linear-gradient(165deg, color-mix(in srgb, var(--info) 9%, var(--surface)), var(--surface) 55%); }
.att-row { padding: 14px 16px; transition: background-color .2s; }
.att-row + .att-row { border-top: 1px solid var(--line); }
.att-row.selected { background: color-mix(in srgb, var(--brand) 9%, transparent); }
.att-main { display: flex; align-items: center; gap: 12px; border-radius: 12px; cursor: pointer; }
.att-main:has(.att-open:focus-visible) { outline: 2px solid var(--light); outline-offset: 4px; }
.att-main .avatar { width: 44px; height: 44px; font-size: 17px; }
.att-row.sent .att-main .avatar { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--info); }
.att-open { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; padding: 0; background: none; border: 0; color: inherit; text-align: start; cursor: pointer; outline: none; }
.att-open .name { max-width: 100%; font-weight: 600; }
.att-open .meta { display: flex; gap: 0 5px; max-width: 100%; min-width: 0; font-size: 13px; color: var(--text-2); }
.att-open .meta .att-when { flex: none; }
.att-open .meta .sep { flex: none; color: var(--text-3); }
/* The receipt itself, small, at the end of the row: tap to review it full screen. */
.att-thumb { position: relative; flex: none; width: 40px; height: 56px; padding: 0; border: 0; border-radius: 9px; overflow: hidden; background: var(--surface-3); box-shadow: 0 0 0 1px var(--line-2), 0 8px 18px -8px rgb(0 0 0 / .6); cursor: zoom-in; transition: transform .25s var(--spring); }
.att-row.sent .att-thumb { box-shadow: 0 0 0 2px color-mix(in srgb, var(--info) 75%, transparent), 0 8px 18px -8px rgb(0 0 0 / .6); }
.att-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.att-thumb .zoom { position: absolute; inset-inline-end: 3px; bottom: 3px; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 6px; background: rgb(0 0 0 / .62); color: #fff; }
.att-thumb .zoom .icon { width: 11px; height: 11px; }
.att-thumb:hover { transform: scale(1.06); }
.att-main .amt { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.att-main .amt b { font-size: 17px; }
.att-main .amt .pill { height: 22px; padding: 0 8px; font-size: 11px; }
.att-note { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding: 8px 12px; border-radius: 12px; background: var(--surface-2); font-size: 13.5px; }
.att-note .icon { flex: none; width: 16px; height: 16px; color: var(--text-3); }
.att-note.faint { background: none; padding: 0 2px; font-size: 12.5px; }
.att-acts { display: grid; grid-template-columns: 1fr 1.6fr; gap: 8px; margin-top: 12px; }
/* More than one waiting: phones show the first and a line for the rest. */
.att-more { display: none; align-items: center; gap: 10px; width: 100%; padding: 12px 16px; border: 0; border-top: 1px solid var(--line); background: color-mix(in srgb, var(--info) 5%, transparent); color: var(--text-2); font-size: 14px; font-weight: 500; text-align: start; cursor: pointer; transition: background-color .2s, color .2s; }
.att-more:hover { color: var(--text); background: color-mix(in srgb, var(--info) 10%, transparent); }
.att-more .avatar-stack .avatar { border-color: var(--surface); }
.att-more > .icon { width: 18px; height: 18px; color: var(--text-3); }
@media (max-width: 1079px) {
  .attention.collapsed .att-row ~ .att-row { display: none; }
  .attention.collapsed .att-more { display: flex; }
}

/* The day strip fades at its edges; past days step back; the month is named once. */
.sched-strip { position: relative; display: flex; align-items: center; gap: 6px; margin: 2px 0 0; }
.sched-strip > .skel { flex: 1; }
.sched-strip .day-strip { flex: 1; min-width: 0; margin-top: -6px; padding-top: 8px; }
.sched-strip .day-strip, .new-booking .day-strip { -webkit-mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
.sched-strip .strip-nav { display: none; }
.sched-strip .day-chip.past, .new-booking .day-chip.past { opacity: .55; }
.sched-strip .day-chip.past.on { opacity: 1; }
.sched-strip .day-chip, .new-booking .day-chip { justify-content: center; }
.sched-strip .day-chip .dm.same, .new-booking .day-chip .dm.same { display: none; }
/* What is left of last night's opening: "Tonight" with stars, as on the customer's sheet. */
.new-booking .day-chip.late { background: linear-gradient(165deg, var(--brand-soft), var(--surface) 75%); border-color: var(--brand-line); }
.new-booking .day-chip.late .dn { display: grid; place-items: center; height: 1.2em; color: var(--brand); }
.new-booking .day-chip.late .dn .icon { width: .95em; height: .95em; }
.new-booking .day-chip.late.on { background: var(--grad, var(--brand)); border-color: transparent; }
.new-booking .day-chip.late.on .dn { color: inherit; }

/* Changing day: the old day dims while the new one loads, then slides in from its side. */
.sched-day { transition: opacity .2s; }
.sched-day.loading { opacity: .45; }
.sched-day[data-dir='next'] { --dx: 1; }
.sched-day[data-dir='prev'] { --dx: -1; }
[dir='rtl'] .sched-day[data-dir='next'] { --dx: -1; }
[dir='rtl'] .sched-day[data-dir='prev'] { --dx: 1; }
.sched-day .day-in { animation: day-in .45s var(--ease-out) both; }
@keyframes day-in { from { opacity: 0; transform: translateX(calc(var(--dx, 0) * 28px)); } }
.sched-day .load-error { margin-top: 18px; }
.sched-summary { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin: 18px 4px 12px; }
.day-title { font-size: 17px; font-weight: 600; }
/* The day in money: earned and coming today, the takings of a day gone, what a day
   ahead should bring; then its visits. Wide screens have it in the summary card. */
.day-money .dm-figs { display: flex; flex-wrap: wrap; gap: 2px 18px; margin-top: 6px; }
.day-money .dm-fig { display: inline-flex; align-items: baseline; }
.day-money .dm-fig .lbl { color: var(--text-2); font-size: 13px; margin-inline-end: 6px; }
.day-money .dm-fig b { font-size: 17px; font-weight: 700; }
.day-money .dm-fig.earned b { color: var(--ok); }
.day-money .dm-sub { margin-top: 2px; }
.staff-filter { margin-bottom: 14px; }
.chip-btn .avatar { width: 24px; height: 24px; font-size: 11px; margin-inline-start: -6px; }
.chip-btn .icon { width: 18px; height: 18px; color: var(--violet, var(--brand)); margin-inline-start: -4px; }
.chip-btn .svc-ic { width: 17px; height: 17px; }

/* The day: time on the start side, a card per visit with a status edge. */
.agenda { display: grid; gap: 10px; }
/* A visit: the whole card opens it (its button is there for the keyboard). Longer
   services stand a little taller. */
.appt { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 8px; cursor: pointer; }
.appt.enter { animation: rise .5s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 40ms); }
.appt .when { padding-top: 13px; text-align: center; line-height: 1.3; }
.appt .when b { display: block; font-size: 14.5px; font-weight: 600; white-space: nowrap; transition: color .2s; }
.appt .when span { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.appt .body { position: relative; display: flex; align-items: center; gap: 12px; min-width: 0; min-height: clamp(66px, calc(var(--dur, 30) * 1.5px), 136px); padding: 12px 14px; border-radius: 18px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow); overflow: hidden; transition: transform .25s var(--spring), border-color .2s, background-color .2s, box-shadow .2s; }
.appt .body::before { content: ''; position: absolute; inset-block: 12px; inset-inline-start: 0; width: 4px; border-start-end-radius: 4px; border-end-end-radius: 4px; background: var(--c, var(--brand)); box-shadow: 0 0 12px var(--c, var(--brand)); }
.appt:hover .body { border-color: var(--line-2); background: var(--surface-2); }
.appt:active .body { transform: scale(.98); }
.appt:has(.appt-open:focus-visible) .body { outline: 2px solid var(--light); outline-offset: 2px; }
.appt .tile { width: 42px; height: 42px; border-radius: 13px; }
.appt-open { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; padding: 0; background: none; border: 0; color: inherit; font-size: inherit; text-align: start; cursor: pointer; outline: none; }
.appt .nm { max-width: 100%; font-weight: 600; font-size: 15.5px; line-height: 1.35; }
.appt .meta { display: flex; align-items: center; gap: 6px; max-width: 100%; font-size: 13px; color: var(--text-2); min-width: 0; }
.appt .meta .appt-svc { min-width: 0; }
.appt .meta .sep { color: var(--text-3); }
.appt .meta .who { flex: 0 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 5px; }
.appt .meta .who .truncate { min-width: 0; }
.appt .meta .avatar { flex: none; width: 18px; height: 18px; font-size: 9px; }
/* The status, under the name so the name keeps the whole line. */
.st-line { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; font-size: 12px; font-weight: 500; }
.st, .live-tag { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.st i, .live-tag i { flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.st-pending_payment { color: var(--warn); }
.st-payment_sent { color: var(--info); }
.st-completed { color: var(--ok); }
.st-no_show { color: var(--danger); }
.st-cancelled, .st-expired { color: var(--text-3); }
/* What the visit is worth, before its arrow. A hold's price is not the salon's yet, nor a
   no-show's (only a deposit kept, which the booking shows), and a cancelled one is struck through. */
.appt .price { flex: none; font-size: 13.5px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
.appt .price.muted, .appt.s-no_show .price { color: var(--text-3); font-weight: 500; }
.appt.s-cancelled .price, .appt.s-expired .price { color: var(--text-3); text-decoration: line-through; }
/* Arrived / no-show (a walk-in: done) once the visit has started, on a line of their
   own under it, so the name, the barber and the price keep their room. A mouse on a wide
   screen gets them on hover instead (see the wide screens' rules). */
.appt .body:has(.appt-quick) { flex-wrap: wrap; row-gap: 10px; }
.appt .body:has(.appt-quick) .appt-open { flex-basis: 0; }
.appt .appt-quick { order: 9; flex-basis: 100%; display: flex; justify-content: flex-end; gap: 8px; }
.appt .appt-quick .btn { padding: 0 16px; border-radius: 12px; }
.appt .chev { display: none; flex: none; width: 18px; height: 18px; }
@media (min-width: 700px) {
  .appt .chev { display: block; }
}
.appt.s-confirmed, .lseg.s-confirmed { --c: var(--ok); }
.appt.s-pending_payment, .lseg.s-pending_payment { --c: var(--warn); }
.appt.s-payment_sent, .lseg.s-payment_sent { --c: var(--info); }
.appt.s-completed, .lseg.s-completed { --c: var(--text-3); }
.appt.s-completed .body { opacity: .72; }
/* A walk-in whose time is up reads as done, and looks it. */
.appt.ended { --c: var(--text-3); }
.appt.ended .body { opacity: .72; }
.appt.s-no_show, .lseg.s-no_show { --c: var(--danger); }
/* Cancelled visits sit apart, below the day: quieter, but plainly drawn. */
.appt.s-cancelled, .appt.s-expired { --c: var(--text-3); }
.appt.s-cancelled .body, .appt.s-expired .body { opacity: .75; box-shadow: none; background: transparent; border-color: var(--line-2); }
.appt.s-cancelled .body::before, .appt.s-expired .body::before { opacity: .45; box-shadow: none; }
.appt.s-cancelled .nm, .appt.s-expired .nm { text-decoration: line-through; text-decoration-color: var(--text-3); }

/* The visit under way: its edge fills as the time passes. */
@property --live-p { syntax: '<number>'; inherits: true; initial-value: 0; }
.appt.live .body { border-color: color-mix(in srgb, var(--now) 38%, var(--line)); background: color-mix(in srgb, var(--now) 7%, var(--surface)); box-shadow: var(--shadow), 0 14px 34px -22px var(--now); }
.appt.live .body::before { background: linear-gradient(to bottom, var(--c) calc(var(--live-p) * 100%), color-mix(in srgb, var(--c) 22%, transparent) 0); animation: live-fill 1.4s var(--ease-out) both; }
@keyframes live-fill { from { --live-p: 0; } }
.appt.live .when b { color: var(--now); }
.live-tag { color: var(--now); font-weight: 600; }
.live-tag i { box-shadow: 0 0 0 3px color-mix(in srgb, var(--now) 25%, transparent); animation: live-dot 1.8s ease-in-out infinite; }
@keyframes live-dot { 50% { box-shadow: 0 0 0 6px transparent; } }

/* Free time between visits (half an hour or more): one thin dashed line, a tap books it. */
.gap-row { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 8px; width: 100%; padding: 0; background: none; border: 0; color: var(--text-3); font-size: 13px; text-align: start; cursor: pointer; }
.gap-rail { justify-self: center; width: 2px; min-height: 36px; border-radius: 2px; background: repeating-linear-gradient(to bottom, var(--line-2) 0 3px, transparent 3px 7px); }
.gap-box { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 36px; padding-block: 4px; padding-inline: 14px 10px; border: 1px dashed var(--line-2); border-radius: 12px; transition: border-color .2s, background-color .2s, color .2s; }
/* The range is what the owner came for: on a narrow phone it drops whole under the
   label instead of being clipped, and the plus stays at the end. */
.gap-text { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; row-gap: 2px; }
.gap-what { flex: none; font-weight: 500; white-space: nowrap; }
.gap-when { white-space: nowrap; opacity: .8; }
.gap-box > .icon { flex: none; width: 17px; height: 17px; margin-inline-start: auto; color: var(--violet, var(--brand)); transition: transform .25s var(--spring); }
.gap-row:not(.now):hover .gap-box, .gap-row:not(.now):focus-visible .gap-box { border-color: var(--brand-line); background: var(--brand-soft); color: var(--text); }
.gap-row:not(.now):hover .gap-box > .icon { transform: scale(1.15) rotate(90deg); }
.gap-row:focus-visible { outline: none; }
.gap-row:focus-visible .gap-box { outline: 2px solid var(--light); outline-offset: 2px; }
/* Free right now, just under the now line: someone who walks in, or a booking for it. */
.gap-row.now { cursor: default; color: var(--text); }
.gap-row.now .gap-rail { background: linear-gradient(to bottom, var(--now), transparent); opacity: .6; }
.gap-row.now .gap-box { flex-wrap: wrap; gap: 8px 10px; padding: 8px; padding-inline-start: 14px; border: 1px solid color-mix(in srgb, var(--now) 32%, var(--line)); background: color-mix(in srgb, var(--now) 6%, var(--surface)); }
.gap-row.now .gap-what { flex: 1 1 auto; font-size: 14px; font-weight: 600; }
.gap-row.now .gap-acts { display: flex; gap: 8px; margin-inline-start: auto; }
.gap-row.now .gap-acts .btn { padding: 0 14px; border-radius: 12px; }
.gap-row.now .gap-acts .icon { width: 18px; height: 18px; }

.cancelled-group { margin-top: 16px; }
.cancelled-group > summary { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 12px; border-radius: 99px; border: 1px solid var(--line); color: var(--text-3); font-size: 13px; font-weight: 500; list-style: none; cursor: pointer; user-select: none; transition: color .2s, border-color .2s; }
.cancelled-group > summary::-webkit-details-marker { display: none; }
.cancelled-group > summary:hover { color: var(--text-2); border-color: var(--line-2); }
.cancelled-group > summary .icon { width: 16px; height: 16px; transition: rotate .25s var(--ease-out); }
.cancelled-group[open] > summary .icon { rotate: 180deg; }
.cancelled-group > .agenda { margin-top: 10px; }

.now-line { display: grid; grid-template-columns: 62px 1fr; gap: 8px; align-items: center; margin: -2px 0; }
.now-line .t { text-align: center; font-size: 11.5px; font-weight: 700; color: var(--now); }
.now-line .l { position: relative; height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--now), color-mix(in srgb, var(--now) 45%, transparent) 45%, transparent); }
[dir='rtl'] .now-line .l { background: linear-gradient(270deg, var(--now), color-mix(in srgb, var(--now) 45%, transparent) 45%, transparent); }
.now-line .l::before { content: ''; position: absolute; inset-inline-start: -5px; top: -4px; width: 10px; height: 10px; border-radius: 50%; background: var(--now); box-shadow: 0 0 0 4px color-mix(in srgb, var(--now) 20%, transparent), 0 0 14px var(--now); animation: now-breathe 2.4s ease-in-out infinite; }
@keyframes now-breathe { 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--now) 8%, transparent), 0 0 20px var(--now); } }

/* A day with nothing booked: its hours, a faint timeline, and how to fill it. */
.empty-day { padding: 20px; }
.empty-day .ed-head { display: flex; align-items: center; gap: 14px; }
.empty-day .tile { width: 52px; height: 52px; border-radius: 16px; }
.empty-day h3 { font-size: 17px; font-weight: 600; }
.empty-day .ed-head p { margin-top: 2px; }
.ghost-tl { display: grid; gap: 8px; margin: 18px 0 14px; }
.ghost-slot { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 8px; align-items: center; opacity: calc(1 - var(--i, 0) * .3); }
.ghost-slot span { font-size: 12px; color: var(--text-3); text-align: center; white-space: nowrap; }
.ghost-slot i { height: 42px; border-radius: 14px; border: 1px dashed var(--line-2); background: linear-gradient(90deg, color-mix(in srgb, var(--brand) 6%, transparent), transparent 70%); }
[dir='rtl'] .ghost-slot i { background: linear-gradient(270deg, color-mix(in srgb, var(--brand) 6%, transparent), transparent 70%); }
.ed-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.ed-actions .btn { flex: 1 1 auto; }
.empty-day.closed { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 28px 20px; text-align: center; }
.empty-day.closed .tile { margin-bottom: 4px; }
.empty-day.closed .btn { margin-top: 8px; }
.empty-day.past { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 22px 16px; border-radius: 18px; border: 1px dashed var(--line); color: var(--text-3); font-size: 14px; }
.empty-day.past .icon { width: 18px; height: 18px; }

/* Booking detail sheet */
.bk-head { display: flex; align-items: flex-start; gap: 12px; }
.bk-head .tile { width: 52px; height: 52px; border-radius: 16px; }
.bk-head .tile .icon { width: 26px; height: 26px; }
.bk-head .name { font-size: 17px; }
.bk-when span { white-space: nowrap; }
.bk-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.bk-tags .pill { height: 24px; padding: 0 9px; gap: 5px; font-size: 11.5px; }
.bk-tags .pill .icon { width: 13px; height: 13px; }
.bk-tags .bk-no { color: var(--text-3); font-weight: 600; }
/* Every line starts at the same place: icons and the barber's photo share a 26px column. */
.bk-detail .kv-ic { flex: none; width: 26px; display: grid; place-items: center; color: var(--text-3); }
/* Booked → deposit sent → confirmed → arrived. */
.bk-steps { list-style: none; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); margin: 16px 0 4px; padding: 12px 4px 10px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); }
.bk-steps li { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; font-size: 11.5px; line-height: 1.3; color: var(--text-3); }
.bk-steps li + li::before { content: ''; position: absolute; top: 10px; inset-inline-start: calc(-50% + 14px); width: calc(100% - 28px); height: 2px; border-radius: 2px; background: var(--line-2); }
.bk-steps li.done + li.done::before { background: var(--grad, var(--brand)); }
.bk-steps .node { position: relative; z-index: 1; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--surface-3); border: 1.5px solid var(--line-2); }
.bk-steps .node .icon { width: 13px; height: 13px; stroke-width: 2.6; }
.bk-steps li.done { color: var(--text-2); }
.bk-steps li.done .node { background: var(--grad, var(--brand)); border-color: transparent; color: var(--on-brand); box-shadow: 0 6px 14px -6px var(--brand-glow); }
.bk-steps li.now { color: var(--text); font-weight: 500; }
.bk-steps li.now .node { border-color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.bk-steps li.bad { color: var(--danger); }
.bk-steps li.bad .node { background: var(--danger); color: var(--bg); box-shadow: none; }
.customer-box { display: flex; align-items: center; gap: 8px; margin-top: 16px; padding-block: 12px; padding-inline: 14px 12px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); }
.customer-box .eyebrow { font-size: 11.5px; }
.customer-box .cb-phone { margin-top: 1px; }
.customer-box .icon-btn { width: 44px; height: 44px; border-radius: 14px; background: var(--surface-3); }
.customer-box .icon-btn.wa { color: #25d366; }
/* The visit's money as far as it has come, a cell per figure. */
.money { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; margin-top: 12px; }
/* A label that wraps (English, a narrow column) pushes its own amount down, so side by side
   the amounts still sit on one line. */
.money > div { display: flex; flex-direction: column; min-width: 0; padding: 10px 12px; border-radius: 14px; border: 1px solid var(--line); }
.money .lbl { flex: 1; font-size: 12px; line-height: 1.4; color: var(--text-3); }
.money b { display: block; margin-top: 2px; font-size: 17px; white-space: nowrap; }
.money small { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-3); }
/* What is still to take at the chair. */
.money .due { background: var(--brand-soft); border-color: var(--brand-line); }
.money .due b { color: var(--violet, var(--brand)); }
/* Money in: paid by CliQ, a visit's takings, a deposit kept. */
.money .ok { background: color-mix(in srgb, var(--ok) 8%, transparent); border-color: color-mix(in srgb, var(--ok) 26%, var(--line)); }
.money .ok b { color: var(--ok); }
/* Not the salon's: a deposit not sent yet, no takings, a cancelled price. */
.money .muted { border-style: dashed; }
.money .muted b { color: var(--text-3); }
.money .struck b { text-decoration: line-through; }
.bk-cancel { display: flex; justify-content: center; margin-top: 14px; }

/* Confirmations: a red mark, the question with the booking in it, a solid red button. */
.confirm-body { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 6px 4px 4px; }
.confirm-tile { display: grid; place-items: center; width: 56px; height: 56px; margin-bottom: 16px; border-radius: 50%; background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); box-shadow: 0 0 0 8px color-mix(in srgb, var(--danger) 6%, transparent); animation: pop .4s var(--spring) both; }
.confirm-tile .icon { width: 26px; height: 26px; }
.confirm-q { max-width: 34ch; font-size: 18px; font-weight: 700; line-height: 1.45; }
.confirm-body .muted { max-width: 42ch; margin-top: 6px; font-size: 14.5px; line-height: 1.6; }
.sched-confirm .sheet-foot .btn { flex: 1; }
.sched-confirm .sheet-foot .btn-danger { background: linear-gradient(135deg, color-mix(in srgb, var(--danger), #000 16%), color-mix(in srgb, var(--danger), #000 36%)); color: #fff; box-shadow: 0 12px 30px -12px color-mix(in srgb, var(--danger) 60%, transparent), inset 0 1px 0 rgb(255 255 255 / .18); }
.sched-confirm .sheet-foot .btn-danger:hover { filter: brightness(1.07); }
.sched-confirm .sheet-foot .btn-danger.busy::after { --stripe: rgb(255 255 255 / .3); }

/* The schedule's sheets: a line under the title once the content scrolls under it. */
.sched-sheet .sheet-head { position: relative; z-index: 2; transition: box-shadow .25s; }
.sched-sheet .sheet-head.scrolled { box-shadow: 0 1px 0 var(--line), 0 12px 22px -16px rgb(0 0 0 / .65); }

/* New booking sheet: one row per hour, :00 :15 :30 :45 beside it. */
.slots-box { margin-top: 12px; }
.slot-hours { display: grid; gap: 14px; }
.slot-hgroup { display: grid; gap: 6px; }
.slot-ghead { display: flex; align-items: center; gap: 8px; margin: 0 2px 2px; font-size: 12.5px; font-weight: 500; color: var(--text-3); }
.slot-ghead .slot-count { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 99px; background: var(--surface-2); font-size: 11px; color: var(--text-2); }
.slot-hour { display: grid; grid-template-columns: 52px repeat(4, minmax(0, 1fr)); gap: 6px; align-items: center; }
.slot-hour .hr { font-size: 13px; font-weight: 600; color: var(--text-2); text-align: center; white-space: nowrap; }
.slot-q { height: 40px; padding: 0; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text); font-size: 14px; font-weight: 600; cursor: pointer; transition: background-color .2s, border-color .2s, transform .2s var(--spring), box-shadow .25s; }
.slot-q:hover { background: var(--surface-3); border-color: var(--brand-line); }
.slot-q:active { transform: scale(.94); }
.slot-q.on { background: var(--grad, var(--brand)); color: var(--on-brand); border-color: transparent; box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), 0 0 0 1px var(--light-line), 0 0 16px -6px var(--light-glow), 0 10px 24px -12px var(--brand-glow); }
.slot-none { height: 40px; border-radius: 12px; border: 1px dashed var(--line); opacity: .45; }
.slot-skel { height: 40px; border-radius: 12px; }
.new-booking .phone-input { margin-top: 12px; }

/* Booking settings */
.card.flush > .switch-row { padding: 12px 16px; }
.card.flush > .switch-row + .switch-row { border-top: 1px solid var(--line); }
.bs-form > * + * { margin-top: 14px; }
.bs-form > .fold:not(.open) { margin-top: 0; }
.bs-group > .price-field { margin-top: 10px; }
.fold .bs-group > .notice { margin-top: 0; }
.fold { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .4s var(--ease-out), opacity .3s; }
.fold.open { grid-template-rows: 1fr; opacity: 1; }
.fold > .fold-inner { min-height: 0; overflow: hidden; padding: 2px; margin: -2px; }
.fold-inner > .eyebrow { margin-bottom: -4px; }
.fold .notice { margin-top: 8px; }

/* Payment screenshots: the customer's picker, their sent copy, the owner's review */
.proof-drop { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px; border-radius: 16px; background: var(--surface-2); border: 1.5px dashed var(--brand-line); text-align: start; cursor: pointer; transition: border-color .2s, background-color .2s, transform .25s var(--spring); }
.proof-drop:hover { background: var(--brand-soft); }
.proof-drop:active { transform: scale(.98); }
.proof-drop .tile { width: 44px; height: 44px; border-radius: 13px; background: var(--brand-soft); color: var(--brand); box-shadow: none; }
.proof-drop b { display: block; font-size: 15px; }
.proof-drop span { font-size: 12.5px; color: var(--text-2); }
/* The picked receipt, whole: shrunk to fit over a blurred copy of itself, so the amount
   and the recipient stay readable however tall the screenshot is. */
.proof-drop.has { position: relative; isolation: isolate; display: block; height: 280px; padding: 0; overflow: hidden; border-style: solid; border-color: var(--line); background: #000; animation: pop .4s var(--spring); }
.proof-drop.has .bg { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; object-fit: cover; filter: blur(22px) saturate(1.3); transform: scale(1.15); opacity: .55; }
.proof-drop.has .fg { width: 100%; height: 100%; padding: 12px; object-fit: contain; filter: drop-shadow(0 10px 24px rgb(0 0 0 / .55)); }
.proof-drop.has .change { position: absolute; top: 10px; inset-inline-end: 10px; display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 99px; background: rgb(0 0 0 / .6); color: #fff; font-size: 13px; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.proof-drop.has .change .icon { width: 16px; height: 16px; }
.proof-drop.invalid { border-color: var(--danger); }
.proof-frame { margin-top: 10px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); overflow: hidden; }
/* The customer's own screenshot, kept short; a tap opens it whole. */
a.proof-frame { position: relative; display: block; cursor: zoom-in; transition: border-color .2s; }
a.proof-frame:hover { border-color: var(--brand-line); }
/* The screenshot sent, inside its step on the timeline: a small look at it (a tap opens
   it whole) beside its replace link. */
.proof-card { display: flex; align-items: center; gap: 14px; margin-top: 10px; padding: 10px 14px 10px 10px; border-radius: 18px; }
[dir='rtl'] .proof-card { padding: 10px 10px 10px 14px; }
.proof-card .proof-frame { flex: none; width: 76px; margin: 0; border-radius: 12px; }
.proof-card .proof-img { display: block; width: 100%; height: 100px; padding: 4px; object-fit: contain; }
.proof-card .proof-zoom { bottom: 6px; inset-inline-end: 6px; width: 26px; height: 26px; }
.proof-card .proof-zoom .icon { width: 13px; height: 13px; }
.proof-side { min-width: 0; display: grid; justify-items: start; gap: 2px; }
.proof-side .link-btn { padding-inline: 0; }
.proof-zoom { position: absolute; bottom: 10px; inset-inline-end: 10px; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--glass, var(--surface)); border: 1px solid var(--line); color: var(--text); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.proof-zoom .icon { width: 16px; height: 16px; }

.proof-strip { display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 12px; padding: 8px; padding-inline-end: 12px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); text-align: start; cursor: pointer; transition: border-color .2s, background-color .2s; }
.proof-strip:hover { border-color: var(--brand-line); background: var(--surface-3); }
.proof-strip img { flex: none; width: 46px; height: 64px; border-radius: 9px; object-fit: cover; object-position: top; background: var(--surface-3); box-shadow: 0 0 0 1px var(--line-2); }
.proof-strip b { display: block; font-size: 14px; font-weight: 600; }
.proof-strip span { font-size: 12.5px; color: var(--info); }

.proof-viewer { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; background: rgb(6 5 16 / .94); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); color: #f4f2ff; animation: fade .25s ease both; }
.proof-viewer.closing { opacity: 0; transition: opacity .2s; }
.proof-viewer.morph, .proof-viewer.morph .pv-stage img { animation: none; }
.pv-top { display: flex; align-items: center; gap: 12px; width: 100%; max-width: 760px; margin: 0 auto; padding: calc(12px + var(--safe-top)) 16px 10px; }
.pv-top .name { font-weight: 600; font-size: 16px; }
.pv-top .muted { color: rgb(228 224 255 / .66); }
.pv-top .icon-btn { width: 42px; height: 42px; border-radius: 14px; background: rgb(255 255 255 / .08); border-color: transparent; color: #fff; }
.pv-count { flex: none; display: inline-grid; place-items: center; height: 28px; padding: 0 10px; border-radius: 99px; background: rgb(255 255 255 / .08); color: rgb(228 224 255 / .8); font-size: 12.5px; font-weight: 600; }
/* What to compare the receipt against: the amount, and the account it should reach. */
.pv-expect { display: flex; align-items: center; gap: 14px; width: calc(100% - 32px); max-width: 560px; margin: 0 auto 10px; padding: 10px 14px; border-radius: 16px; background: color-mix(in srgb, var(--info) 13%, rgb(255 255 255 / .03)); border: 1px solid color-mix(in srgb, var(--info) 32%, transparent); }
.pv-amt { flex: none; }
.pv-amt span { display: block; font-size: 11.5px; color: rgb(228 224 255 / .7); }
.pv-amt b { display: block; font-size: 22px; font-weight: 700; line-height: 1.25; color: #fff; }
.pv-to { display: flex; flex-direction: column; gap: 1px; padding-inline-start: 14px; border-inline-start: 1px solid rgb(255 255 255 / .14); font-size: 13px; color: rgb(228 224 255 / .78); }
.pv-to .pv-alias { direction: ltr; unicode-bidi: isolate; font-weight: 600; color: #fff; }
/* The receipt fits the screen whole; zoomed, it scrolls under soft edges. */
.pv-stage { flex: 1; min-height: 0; overflow: auto; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; padding: 4px 16px; overscroll-behavior: contain; }
.pv-stage img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 14px; box-shadow: 0 30px 60px -20px #000; cursor: zoom-in; animation: pop .45s var(--spring) both; }
.pv-stage.zoomed { display: block; -webkit-mask-image: linear-gradient(transparent, #000 28px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(transparent, #000 28px, #000 calc(100% - 28px), transparent); }
.pv-stage.zoomed img { max-width: none; max-height: none; width: min(1400px, 200%); margin: 14px auto; cursor: zoom-out; }
::view-transition-group(proof) { animation-duration: .5s; animation-timing-function: var(--ease-out); }
::view-transition-old(proof), ::view-transition-new(proof) { animation-duration: .5s; }
html.vt-proof::view-transition-old(root) { animation: pv-root-out .3s ease both; }
html.vt-proof::view-transition-new(root) { animation: fade .3s ease both; }
@keyframes pv-root-out { to { opacity: 0; } }
.pv-foot { padding: 12px 16px calc(14px + var(--safe-bottom)); max-width: 560px; width: 100%; margin: 0 auto; }
.pv-hint { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 12px; font-size: 13px; line-height: 1.5; color: #fcd34d; }
.pv-hint .icon { flex: none; width: 17px; height: 17px; margin-top: 1px; }
.pv-hint.faint { justify-content: center; color: rgb(228 224 255 / .5); }
.pv-actions { display: grid; grid-template-columns: 1fr 1.6fr; gap: 10px; }
.pv-actions .btn-secondary { background: rgb(255 255 255 / .08); border-color: rgb(255 255 255 / .12); color: #fff; }

/* Wide screens: the day beside a column with the deposits, the day in figures and the
   open booking. The app preview steps aside on this page. */
.sched-detail { padding: 18px; }
.sched-detail .sd-head { display: flex; align-items: center; gap: 8px; margin: -6px 0 12px; margin-inline-end: -8px; }
.sched-detail .sd-head h2 { flex: 1; min-width: 0; font-size: 17px; font-weight: 600; outline: none; }
.sched-detail .sd-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; margin-top: 16px; }
.sched-detail .sd-actions:has(> :nth-child(2)) { grid-template-columns: 1fr 1.6fr; }
.sched-detail .sd-actions .btn { height: 46px; }
.sched-stats { padding: 18px; }
.sched-stats > h2 { margin-bottom: 10px; }
.kpis-s { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.kpi-s { min-width: 0; padding: 10px; padding-inline: 11px 8px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); }
.kpi-s span, .kpi-s b { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-s span { font-size: 11.5px; color: var(--text-3); }
.kpi-s b { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
/* Each chair's day as a bar: open hours lit, visits in their status colour, now marked. */
.lanes { display: grid; gap: 9px; margin-top: 16px; }
.lane, .lanes .scale { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 8px; align-items: center; }
.lane .avatar { width: 22px; height: 22px; font-size: 10px; }
.lane .ltrack { position: relative; height: 14px; border-radius: 7px; background: color-mix(in srgb, var(--bg) 70%, transparent); overflow: hidden; }
.lane .lopen { position: absolute; inset-block: 0; inset-inline-start: calc(var(--a) * 100%); width: calc(var(--w) * 100%); background: var(--surface-3); }
.lane .lseg { position: absolute; inset-block: 2px; inset-inline-start: calc(var(--a) * 100%); width: max(6px, calc(var(--w) * 100% - 1px)); border-radius: 4px; background: var(--c, var(--ok)); box-shadow: 0 0 10px -2px var(--c, var(--ok)); }
.lane .now-tick { position: absolute; inset-block: 0; inset-inline-start: calc(var(--a) * 100%); width: 2px; background: var(--now); box-shadow: 0 0 8px var(--now); }
.lanes .scale > div { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-3); }
/* The owner's: what each chair brings in the day, at the end of its bar, one column for all. */
.lanes.amts { grid-template-columns: 22px minmax(0, 1fr) auto; column-gap: 8px; }
.lanes.amts > .lane, .lanes.amts > .scale { grid-column: 1 / -1; grid-template-columns: subgrid; }
.lane-amt { font-size: 12px; font-weight: 600; color: var(--text-2); text-align: end; white-space: nowrap; }
.next-up { display: flex; align-items: center; gap: 10px; width: 100%; margin-top: 16px; padding: 12px 14px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text); font-size: 14px; text-align: start; cursor: pointer; transition: border-color .2s, background-color .2s; }
.next-up:hover { border-color: var(--brand-line); background: var(--surface-3); }
.next-up .eyebrow { flex: none; }
.next-up .when { flex: none; font-weight: 600; color: var(--violet, var(--brand)); }
@media (min-width: 1080px) {
  .studio[data-page='bookings'] .s-preview { display: none; }
  .studio[data-page='bookings'] .s-main { grid-column: 2 / -1; }
  .studio[data-page='bookings'] .s-page { max-width: 1180px; }
  .s-side a.nav .badge-count { position: static; margin-inline-start: auto; box-shadow: none; }
  .sched .add-btn { padding: 0 18px; gap: 8px; }
  .sched-cols { display: grid; grid-template-columns: minmax(0, 1fr) 360px; column-gap: 32px; align-items: start; }
  .sched-main { display: block; min-width: 0; }
  .sched-side { display: flex; flex-direction: column; gap: 18px; position: sticky; top: 24px; max-height: calc(100dvh - 48px); margin: -6px; padding: 6px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  .sched-detail-box, .sched-stats-box { display: block; }
  .sched-detail-box:empty, .sched-stats-box:empty, .sched-attention:empty { display: none; }
  .sched-side .attention { margin: 0; }
  .sched-side .takings-section { margin: 0; }
  .sched-summary .day-money { display: none; }
  .sched-strip .strip-nav { display: inline-grid; width: 36px; height: 36px; border-radius: 12px; }
  .sched-strip .day-strip { margin-inline: 0; padding-inline: 10px; scroll-padding-inline: 10px; }
  .appt .price { font-size: 14.5px; }
  .appt.selected .body { border-color: var(--brand-line); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); box-shadow: 0 0 0 1px var(--brand-line), var(--shadow); }
}
/* A mouse: arrived / no-show on hover, over the end of the card (touch screens keep them
   on their own line, as on phones). */
@media (min-width: 1080px) and (hover: hover) {
  .appt .appt-quick { position: absolute; inset-block: 0; inset-inline-end: 0; align-items: center; gap: 6px; padding-inline: 52px 12px; background: linear-gradient(to right, transparent, var(--surface-2) 44px); opacity: 0; pointer-events: none; transition: opacity .2s; }
  [dir='rtl'] .appt .appt-quick { background: linear-gradient(to left, transparent, var(--surface-2) 44px); }
  .appt:hover .appt-quick, .appt:focus-within .appt-quick { opacity: 1; pointer-events: auto; }
  .appt .appt-quick .btn { height: 34px; padding: 0 12px; border-radius: 10px; font-size: 13px; }
}
@media (min-width: 1080px) and (max-width: 1279px) {
  .sched-cols { grid-template-columns: minmax(0, 1fr) 320px; column-gap: 24px; }
}

/* A barber still on the temporary password the owner handed him (the owner's own
   reminder is a line on Home under "needs you"). */
.card.temp-pw { margin-top: 16px; border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); background: linear-gradient(160deg, color-mix(in srgb, var(--warn) 10%, var(--surface)), var(--surface) 60%); }
.card.temp-pw .tile { background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); }
/* Icon | text, and the button under the text (not under the icon); beside it on desktop. */
.card.temp-pw { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 14px; row-gap: 12px; align-items: center; }
.card.temp-pw > .btn { grid-column: 2; justify-self: start; }
@media (min-width: 1080px) {
  .card.temp-pw { grid-template-columns: auto minmax(0, 1fr) auto; }
  .card.temp-pw > .btn { grid-column: 3; }
}
/* The first load failed: why, and a way to try again. */
.load-error { margin-top: 24px; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.load-error .tile { margin: 0; background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.load-error p { max-width: 32ch; color: var(--text); }

/* Takings: what is earned so far, large; what is still to come as a bar and a line;
   what waits on a deposit apart; then the days and the team. Calm: no glow, the
   figure counts up once. Narrow (a side column) or wide, everything wraps. */
.tk-head { align-items: center; flex-wrap: wrap; row-gap: 8px; }
.segmented.sm { gap: 2px; padding: 3px; border-radius: 13px; }
.segmented.sm span { height: 32px; padding-inline: 12px; border-radius: 10px; font-size: 13px; white-space: nowrap; }
.takings-card { padding: 18px; container: takings / inline-size; }
.takings-card .tk-big .lbl { display: block; color: var(--text-2); font-size: 13.5px; }
/* The figure reads like an instrument: thin digits, the currency small beside them. */
.takings-card .tk-big .fig { display: flex; width: fit-content; margin-top: 4px; }
.takings-card .tk-big .fig.xl { font-size: clamp(40px, 15cqi, 60px); }
.takings-card .tk-bar { height: 6px; border-radius: 99px; margin-top: 12px; background: color-mix(in srgb, var(--brand) 38%, var(--surface-2)); overflow: hidden; }
.takings-card .tk-bar::before { content: ''; display: block; height: 100%; width: calc(var(--p) * 100%); border-radius: inherit; background: var(--ok); }
.takings-card .tk-split { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin-top: 8px; font-size: 13.5px; color: var(--text-2); }
.takings-card .tk-item { display: inline-flex; align-items: center; gap: 4px; }
.takings-card .tk-item b { color: var(--text); font-weight: 600; }
.takings-card .tk-end { margin-inline-start: auto; }
.takings-card .tk-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; margin-inline-end: 2px; }
.takings-card .tk-dot.done { background: var(--ok); }
.takings-card .tk-dot.coming { background: var(--brand); }
.takings-card .tk-meta { margin-top: 10px; }
.takings-card .tk-await { display: flex; align-items: center; gap: 10px; margin-top: 12px; padding: 10px 12px; border-radius: 14px; font-size: 14px; }
.takings-card .tk-await { background: color-mix(in srgb, var(--warn) 12%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--warn) 26%, transparent); color: var(--text); text-decoration: none; transition: border-color .2s; }
.takings-card .tk-await:hover { border-color: color-mix(in srgb, var(--warn) 50%, transparent); }
.takings-card .tk-await > .icon:first-child { width: 18px; height: 18px; color: var(--warn); }
.takings-card .tk-await > .icon:last-child { width: 17px; height: 17px; }
/* What came in by CliQ: a plain line under the figures, never a box to add to them. */
.takings-card .tk-received { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.takings-card .tk-received .icon { width: 15px; height: 15px; flex: none; color: var(--ok); }
.takings-card .tk-staff-box { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.takings-card .tk-staff-box > .eyebrow { margin-bottom: 10px; }
.takings-card .tk-staff { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; }
.takings-card .tk-staff li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 10px; row-gap: 6px; }
.takings-card .tk-staff .avatar { width: 34px; height: 34px; font-size: 13px; }
.takings-card .tk-staff .name { font-size: 14.5px; font-weight: 600; }
.takings-card .tk-staff li > b { font-size: 15px; font-weight: 700; }
.takings-card .tk-staff li.paused .name { color: var(--text-2); }
/* The share: earned solid, still to come faint, both against the busiest chair. */
.takings-card .tk-share { grid-column: 2 / -1; height: 4px; border-radius: 99px; background: linear-gradient(to right, var(--ok) 0 calc(var(--e) * 100%), color-mix(in srgb, var(--brand) 55%, transparent) 0 calc((var(--e) + var(--u)) * 100%), var(--surface-2) 0); }
[dir='rtl'] .takings-card .tk-share { transform: scaleX(-1); }
.takings-card .tk-rule { margin-top: 16px; line-height: 1.6; }
.takings-card .tk-failed { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.takings-card .chart { margin-top: 18px; }
/* The plan on a column: faint, dashed, behind the readout's highlight. */
.chart .bar.plan { fill: color-mix(in srgb, var(--brand) 16%, transparent); stroke: color-mix(in srgb, var(--brand) 60%, transparent); stroke-width: 1; stroke-dasharray: 3 2; }
.chart .bar.plan.on { fill: color-mix(in srgb, var(--brand) 30%, transparent); }
.chart-tip .tip-plan { color: var(--brand); font-weight: 500; }
/* A wide card: the team beside the figures. */
@container takings (min-width: 640px) {
  .takings-card .tk-staff { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
}

/* Settings sheet: fields with an icon at their start, the password behind its own
   row, and signing out as a quiet line above the legal links. */
/* By the page's side, not the field's: an Arabic note in the English studio keeps clear of the icon. */
[dir='ltr'] .f.has-icon > input, [dir='ltr'] .f.has-icon > textarea { padding-left: 48px; }
[dir='rtl'] .f.has-icon > input, [dir='rtl'] .f.has-icon > textarea { padding-right: 48px; }
.f.has-icon > .label { inset-inline-start: 49px; max-width: calc(100% - 66px); }
.f.has-icon > .f-icon { position: absolute; inset-inline-start: 16px; top: 20px; display: grid; color: var(--text-3); pointer-events: none; transition: color .2s; }
.f.has-icon > .f-icon .icon { width: 19px; height: 19px; }
.f.has-icon:focus-within > .f-icon { color: var(--brand); }
.settings-form .phone-input + .f { margin-top: 12px; }
.account-row { margin-bottom: 6px; }
.account-row .phone-line { font-weight: 600; }
[dir='rtl'] .account-row .phone-line { text-align: right; }
.disclosure { display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 10px; padding: 12px; border-radius: var(--r); background: var(--surface-2); border: 1px solid var(--line); color: var(--text); text-align: start; cursor: pointer; transition: background-color .2s, border-color .2s; }
.disclosure:hover { background: var(--surface-3); }
.disclosure .tile { width: 40px; height: 40px; border-radius: 12px; }
.disclosure .tile .icon { width: 19px; height: 19px; }
.disclosure .title { font-weight: 500; font-size: 15px; }
.disclosure .sub { font-size: 12.5px; color: var(--text-2); }
.disclosure > .chev { color: var(--text-3); transition: transform .35s var(--ease-out); }
.disclosure.open { border-color: var(--brand-line); }
.disclosure.open > .chev { transform: rotate(180deg); color: var(--brand); }
.fold > .pw-fields { padding: 12px 4px 4px; margin: 0 -4px -4px; }
.pw-fields > .btn { margin-top: 12px; }
.settings-end { margin-top: 26px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.logout-btn { color: var(--danger); }
.logout-btn:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.settings-end .legal-links.in-sheet { margin-top: 10px; }
.settings-form > .section:first-child { margin-top: 0; }
.info-form { display: grid; gap: 12px; }
.info-form .phone-input + .f { margin-top: 0; }

/* My salon: the pages set once, as rows saying where each stands. */
.hub-row { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 72px; padding: 14px; color: var(--text); text-align: start; background: none; border: 0; border-top: 1px solid var(--line); cursor: pointer; transition: background-color .2s, scale var(--t-release) var(--spring-soft); }
/* Rows that open something give under the finger, as buttons do. */
:is(a.hub-row, button.hub-row, a.today-row):active { scale: .985; transition-duration: .2s, var(--t-press); }
.hub-list > :first-child { border-top: 0; }
a.hub-row:hover, button.hub-row:hover { background: var(--surface-2); }
.hub-row:focus-visible { outline-offset: -2px; }
.hub-row .tile { width: 42px; height: 42px; border-radius: 13px; }
.hub-row .tile .icon { width: 20px; height: 20px; }
.hub-row > .app-icon { --s: 42px; border-radius: 12px; }
.hub-row .title { font-weight: 600; line-height: 1.35; }
.hub-row .sub { margin-top: 1px; font-size: 13px; line-height: 1.45; color: var(--text-2); }
.hub-row .sub.warn { color: var(--warn); }
.hub-row > .faint { flex: none; width: 18px; height: 18px; }
.hub-row .badge-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.hub-row .avatar-stack .avatar { width: 28px; height: 28px; font-size: 11.5px; border-color: var(--surface); }
.hub-row .hub-mark { --s: 30px; border-radius: 9px; box-shadow: 0 0 0 1px var(--line-2); }
.hub-row.static { cursor: default; }
.hub-link { cursor: default; }
/* The link whole, left to right on its own side; a long one breaks rather than hides its end. */
.hub-link .url { direction: ltr; unicode-bidi: isolate; text-align: start; overflow-wrap: anywhere; font-weight: 500; color: var(--text); }
[dir='rtl'] .hub-link .url { text-align: end; }
.hub-link .icon-btn { flex: none; width: 40px; height: 40px; border-radius: 12px; background: var(--surface-2); }
@media (min-width: 1080px) {
  /* The sidebar lists the team, the hours and the brand. */
  .hub .hub-pages { display: none; }
  /* The guide's section leads, flush under the title, as the first one does on a phone. */
  .hub .hub-guide { margin-top: 0; }
}

/* The preview sheet: the phone centred under the switch, in a soft spotlight. */
.pv-phone { position: relative; isolation: isolate; display: grid; justify-items: center; }
.sheet .pv-phone::before { content: ''; position: absolute; z-index: -1; inset: 6% -10% 10%; border-radius: 50%; background: radial-gradient(closest-side, var(--brand-soft), transparent); pointer-events: none; }
/* The live preview as a hologram of the salon's app: an iridescent rim in the light's two
   colours, a faint scan over the glass, the projector's light pooled under it. All still. */
.pv-phone .phone {
  box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / .14), 0 0 0 1px color-mix(in srgb, var(--neon-a) 30%, transparent), 0 0 38px -10px color-mix(in srgb, var(--neon-a) 55%, transparent),
    0 50px 90px -40px rgb(0 0 0 / .95);
}
.pv-phone .phone::before {
  content: ''; position: absolute; inset: -1px; z-index: 6; border-radius: inherit; padding: 1.5px; pointer-events: none; opacity: .8;
  background: conic-gradient(from 200deg, var(--neon-a), transparent 16%, rgb(255 255 255 / .7) 26%, transparent 36%, var(--neon-b) 52%, transparent 66%, rgb(255 255 255 / .5) 78%, transparent 88%, var(--neon-a));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
}
.pv-phone .phone-screen::after {
  content: ''; position: absolute; inset: 0; z-index: 6; border-radius: inherit; pointer-events: none;
  background: linear-gradient(125deg, transparent 32%, rgb(255 255 255 / .06) 42%, color-mix(in srgb, var(--neon-a) 9%, transparent) 46%, transparent 55%), repeating-linear-gradient(180deg, rgb(255 255 255 / .022) 0 1px, transparent 1px 4px);
}
.pv-phone::after {
  content: ''; position: absolute; z-index: -1; left: 50%; bottom: -16px; width: 74%; max-width: 260px; height: 34px; translate: -50% 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, transparent 80%, color-mix(in srgb, var(--neon-a) 45%, transparent) 86%, transparent 92%), radial-gradient(closest-side, color-mix(in srgb, var(--neon-a) 30%, transparent), transparent);
}

/* ==========================================================================
   Platform dashboard
   ========================================================================== */
.trend-card { padding: 20px 18px 10px; }
.trend-head { position: relative; z-index: 1; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px 28px; flex-wrap: wrap; }
.trend-main { min-width: 0; }
.trend-main > .eyebrow { margin: 0; line-height: 1.5; }
/* The month's figure and the week's pill read as one line, on one baseline. */
.trend-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; }
.trend-side { display: none; margin: 0; }
.trend-side > div { padding-inline-start: 14px; border-inline-start: 1px solid var(--line-2); }
.trend-side dt { font-size: 12.5px; color: var(--text-3); }
.trend-side dd { display: flex; align-items: baseline; gap: 8px; margin: 2px 0 0; white-space: nowrap; }
.trend-side dd b { font-size: 21px; font-weight: 700; line-height: 1.3; }
.trend-side dd span { font-size: 12.5px; color: var(--text-2); }
@media (min-width: 700px) { .trend-side { display: flex; gap: 26px; padding-bottom: 6px; } }
.hero-figure { margin-top: 4px; font-size: 54px; font-weight: var(--w-figure); line-height: 1.05; color: var(--text); font-variant-numeric: tabular-nums; }
:lang(en) .hero-figure { letter-spacing: -.02em; }
.delta { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: 999px; font-size: 12.5px; font-weight: 500; color: var(--text-2); background: var(--surface-2); border: 1px solid var(--line); }
.delta .icon { width: 16px; height: 16px; }
.delta-in { display: inline-flex; align-items: center; gap: 6px; }
.delta b { font-weight: 700; }
.delta.up { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); border-color: transparent; }
.delta.down { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: transparent; }
.flip-v { transform: scaleY(-1); }

/* The chart: a rounded column per day in the studio's light, ghost ticks for empty
   days, hairlines; values in text colours. */
.chart { position: relative; z-index: 1; margin-top: 14px; }
.chart-plot { position: relative; border-radius: 12px; outline: none; touch-action: pan-y; cursor: crosshair; }
.chart-plot:focus-visible { box-shadow: 0 0 0 2px var(--brand); }
.chart svg { display: block; overflow: visible; }
.chart .grid { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.chart .grid.base { stroke: var(--line-2); }
.chart .tick { fill: var(--text-3); font: 11.5px var(--font); font-variant-numeric: tabular-nums; }
.chart .g-top { stop-color: var(--glow-1, var(--brand)); }
.chart .g-bottom { stop-color: var(--glow-3, var(--brand)); }
.chart .bar { transition: opacity .2s, filter .2s; }
.chart .bar.zero { fill: var(--line-2); }
.chart .bar.last:not(.zero), .chart .bar.on:not(.zero) { filter: drop-shadow(0 0 8px color-mix(in srgb, var(--glow-1, var(--brand)) 70%, transparent)); }
.chart .hovering .bar:not(.on):not(.zero) { opacity: .55; }
.chart .bar.on.zero { fill: var(--text-3); }
.chart .lane { fill: color-mix(in srgb, var(--brand) 9%, transparent); }
.chart .cross { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 2 3; shape-rendering: crispEdges; }
@media (prefers-reduced-motion: no-preference) {
  .chart .bar.enter { transform-box: fill-box; transform-origin: 50% 100%; animation: bar-grow .75s var(--ease-out) both; animation-delay: calc(120ms + var(--i, 0) * 22ms); }
}
@keyframes bar-grow { from { transform: scaleY(0); } }
.chart-tip { position: absolute; z-index: 3; display: flex; flex-direction: column; align-items: center; padding: 6px 11px; border-radius: 11px; background: var(--surface-3); border: 1px solid var(--line-2); box-shadow: var(--shadow-lg); line-height: 1.3; white-space: nowrap; pointer-events: none; }
.chart-tip b { font-size: 15px; font-weight: 700; }
.chart-tip span { font-size: 11.5px; color: var(--text-2); }
.chart-foot { display: flex; justify-content: flex-end; }
.chart-toggle { font-size: 12.5px; }
.chart-table { display: block; max-height: 280px; overflow: auto; width: 100%; border-collapse: collapse; font-size: 13.5px; }
.chart-table thead, .chart-table tbody { display: table; width: 100%; }
.chart-table th { text-align: start; font-weight: 500; color: var(--text-3); font-size: 12px; padding: 6px 4px; border-bottom: 1px solid var(--line-2); }
.chart-table td { padding: 8px 4px; border-bottom: 1px solid var(--line); }
.chart-table td.num, .chart-table th:last-child { text-align: end; }

.kpis { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 12px; }
.kpi { position: relative; overflow: hidden; padding: 14px 14px 16px; border-radius: 20px; background: linear-gradient(165deg, rgb(255 255 255 / .045), transparent 45%), var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow); }
/* A thin light along the top edge, like a lit shelf. */
.kpi::before { content: ''; position: absolute; top: 0; inset-inline: 16px; height: 1px; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--glow-1-soft) 55%, transparent), transparent); }
.kpi-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.kpi-icon { flex: none; width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center; background: var(--grad-soft, var(--brand-soft)); color: var(--violet, var(--brand)); }
.kpi-icon .icon { width: 16px; height: 16px; }
.kpi-label { font-size: 12.5px; font-weight: 500; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-value { margin-top: 12px; font-size: 32px; font-weight: var(--w-figure); line-height: 1.1; color: var(--text); font-variant-numeric: tabular-nums; }
.kpi-sub { margin-top: 3px; font-size: 12.5px; color: var(--text-3); }
.meter { margin-top: 10px; height: 4px; border-radius: 99px; background: color-mix(in srgb, var(--brand) 18%, transparent); overflow: hidden; }
.meter i { display: block; width: calc(var(--v) * 100%); height: 100%; border-radius: inherit; background: var(--grad); transform-origin: left; animation: grow 1.1s var(--ease-out) .4s both; }
[dir='rtl'] .meter i { transform-origin: right; }

.search-box { display: flex; align-items: center; gap: 10px; height: 50px; padding: 0 16px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line); transition: border-color .2s, box-shadow .2s; }
.search-box:focus-within { border-color: var(--brand-line); box-shadow: 0 0 0 4px var(--brand-soft); }
.search-box .icon { flex: none; width: 19px; height: 19px; color: var(--text-3); }
.search-input { flex: 1; min-width: 0; height: 100%; padding: 0; background: none; border: 0; outline: none; font-size: 15px; color: var(--text); }
.search-input::placeholder { color: var(--text-3); }
.search-input::-webkit-search-cancel-button { filter: invert(1) opacity(.45); }
.filter-row { margin-top: 12px; }
.chip-count { display: inline-grid; place-items: center; min-width: 22px; height: 20px; padding: 0 6px; border-radius: 99px; background: var(--surface-3); color: var(--text-2); font-size: 11.5px; font-weight: 600; }
.chip-btn.on .chip-count { background: var(--brand); color: #fff; }

/* Four filters fit a 400px phone in Arabic and in English; the strip's edge fades
   where more waits (the studio .scroller's scroll-driven mask). Engines without
   scroll timelines get a still fade as wide as the strip's end padding, so it only
   touches a chip when the row really runs on. */
.filter-row { gap: 4px; }
.filter-row .chip-btn { gap: 5px; height: 40px; padding: 0 8px; font-size: 13.5px; }
@supports not (animation-timeline: scroll()) {
  .filter-row { -webkit-mask-image: linear-gradient(to left, transparent, #000 var(--bleed)); mask-image: linear-gradient(to left, transparent, #000 var(--bleed)); }
  [dir='rtl'] .filter-row { -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--bleed)); mask-image: linear-gradient(to right, transparent, #000 var(--bleed)); }
}
.filter-row .chip-count { min-width: 20px; padding: 0 5px; font-size: 11px; }
/* Filters, and on wide screens the cards / rows switch beside them. */
.salon-tools { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.salon-tools .filter-row { flex: 1; min-width: 0; margin-top: 0; }
.layout-toggle { display: none; flex: none; gap: 2px; padding: 3px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line); }
.layout-toggle .icon-btn { width: 38px; height: 34px; border-radius: 10px; background: transparent; border-color: transparent; color: var(--text-3); }
.layout-toggle .icon-btn:hover { color: var(--text); background: var(--surface-2); }
.layout-toggle .icon-btn[aria-pressed='true'] { background: var(--surface-3); color: var(--text); }
.layout-toggle .icon { width: 18px; height: 18px; }
.salons .section-head .count { margin-inline-start: 8px; }
.salon-results { margin-top: 16px; }
.salon-group + .salon-group { margin-top: 24px; }
.group-label { display: flex; align-items: center; gap: 8px; margin: 0 4px 10px; font-size: 13px; font-weight: 600; line-height: 1.4; color: var(--text-2); }
.group-label.warn { color: var(--text); }
.group-label.warn::before { content: ''; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--warn); box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 16%, transparent); }
.salon-list-head { display: none; }

.salon-grid { display: grid; gap: 10px; }
/* A salon in about 110px: who, where, status; one line of activity under it. */
.salon-card { position: relative; isolation: isolate; overflow: hidden; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px 12px; width: 100%; padding: 14px; border-radius: 20px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow); text-align: start; cursor: pointer; transition: transform .35s var(--spring), border-color .25s, box-shadow .25s, background-color .2s; }
.salon-card.setup { border-color: color-mix(in srgb, var(--warn) 16%, var(--line)); }
.sc-id { min-width: 0; }
.sc-setup { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; }
.salon-card:not(.setup) .sc-setup { display: none; }
.sc-setup .segs { flex: 1; display: grid; grid-template-columns: repeat(var(--n, 9), 1fr); gap: 3px; }
.sc-setup b { display: none; font-size: 11.5px; font-weight: 600; color: var(--text-3); }
/* Bookings, then the owner's last visit; when both do not fit on one line the visit
   takes a line of its own rather than lose its time. */
.sc-line { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; min-width: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-2); }
.sc-book, .sc-seen { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.sc-book { flex: none; max-width: 58%; }
.sc-seen { flex: 1 1 auto; color: var(--text-3); }
.sc-line .icon { flex: none; width: 14px; height: 14px; color: var(--text-3); }
.salon-card:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--shadow), 0 22px 44px -26px var(--brand-glow); }
.salon-card:active { transform: scale(.98); }
/* A mirror glint crosses the card on hover. */
.salon-card::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / .06) 45%, rgb(196 181 253 / .12) 50%, transparent 62%); transform: translateX(-120%); transition: transform 1s var(--ease-out); pointer-events: none; }
.salon-card:hover::after { transform: translateX(120%); }
.sc-avatar { position: relative; flex: none; }
.sc-icon { width: 46px; height: 46px; border-radius: 14px; overflow: hidden; background: var(--surface-3); box-shadow: 0 0 0 1px var(--line-2); }
.sc-icon img { width: 100%; height: 100%; object-fit: cover; }
.sc-icon .mark { width: 100%; height: 100%; display: grid; place-items: center; background: var(--grad); }
.sc-icon .mark svg { width: 72%; height: 72%; }
.live-dot { position: absolute; bottom: -3px; inset-inline-end: -3px; width: 14px; height: 14px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--surface); }
.live-dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--ok); animation: ping 2.4s var(--ease-out) infinite; }
.salon-card.setup .live-dot { background: var(--warn); }
.salon-card.setup .live-dot::after { border-color: var(--warn); }
.salon-card.suspended .live-dot { background: var(--text-3); }
.salon-card.suspended .live-dot::after { display: none; }
.salon-card.suspended .sc-icon { filter: grayscale(1) opacity(.7); }
.salon-card .name { font-size: 15.5px; font-weight: 600; line-height: 1.4; }
.salon-card .link, .sd-hero .link { direction: ltr; unicode-bidi: isolate; font-size: 12.5px; color: var(--text-3); }
[dir='rtl'] .salon-card .link, [dir='rtl'] .sd-hero .link { text-align: right; }
.sc-setup i { height: 4px; border-radius: 99px; background: var(--surface-3); }
.sc-setup i.on { background: var(--grad); box-shadow: 0 0 10px -2px var(--brand-glow); }
.pill.warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 13%, transparent); border-color: transparent; }
.pill.tiny { flex: none; height: 20px; padding: 0 8px; font-size: 10.5px; }
/* The owner's name gives way first; when they were last here, and a temporary
   password, always show in full. In a narrow card (a 2-column tablet grid, a small
   phone) the pill takes a line of its own rather than run past the card's edge. */
.sc-seen .pill.tiny { flex: none; margin-inline-start: 2px; }
.salon-card { container: salon-card / inline-size; }
@container salon-card (max-width: 329px) { .sc-seen { flex-wrap: wrap; row-gap: 4px; } }
.sc-who { min-width: 3ch; }
.sc-when { flex: none; white-space: nowrap; }
/* The separator sits a space from the name: "Name · 2 hours ago", "الاسم، قبل ساعتين". */
.sc-who + .sc-when { margin-inline-start: -2px; }
[dir='rtl'] .sc-who + .sc-when { margin-inline-start: -6px; }

/* Salon detail */
.sd > * + * { margin-top: 14px; }
.sd-hero { display: flex; align-items: center; gap: 14px; }
/* The salon's icon in a ring of the studio's light: it turns one lap as the sheet opens, then rests. */
.sd-icon { flex: none; padding: 3px; border-radius: 23px; background: conic-gradient(from var(--angle), var(--glow-1), var(--glow-2), var(--glow-3), var(--glow-1)); animation: orbit 6s var(--ease-out) 1; }
.sd-icon .sc-icon { width: 62px; height: 62px; border-radius: 20px; box-shadow: 0 0 0 3px var(--bg-2); }
.sd-hero.suspended .sd-icon { animation: none; background: var(--surface-3); }
.sd-hero.suspended .sc-icon { filter: grayscale(1); }
.sd-hero .link { font-size: 15px; font-weight: 600; color: var(--text); }
.sd-hero .icon-btn { flex: none; }
.sd-links { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sd-links .btn { width: 100%; }
.sd-live { padding: 8px 16px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); }
.sd-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.sd-stat { min-width: 0; padding: 12px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); }
.sd-stat b { display: block; overflow: hidden; font-size: 19px; line-height: 1.25; white-space: nowrap; text-overflow: ellipsis; }
/* Words ("3 hours ago") sit smaller than the counts beside them, on the same line height. */
.sd-stat b.text { font-size: 15px; font-weight: 600; line-height: 1.58; }
.sd-stat span { font-size: 12.5px; color: var(--text-3); }
/* A salon with nothing to count yet: one calm row and a nudge, not six zeros. */
.sd-quiet { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 14px; padding: 16px; border-radius: 18px; background: linear-gradient(160deg, var(--brand-soft), transparent 65%), var(--surface-2); border: 1px dashed var(--line-2); }
.sd-quiet-ic { flex: none; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 13px; background: var(--grad-soft, var(--brand-soft)); color: var(--violet, var(--brand)); }
.sd-quiet .grow { min-width: 0; flex: 1 1 200px; }
.sd-quiet b { display: block; font-size: 15px; font-weight: 600; line-height: 1.45; }
.sd-quiet .grow span { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.5; color: var(--text-2); }
.sd-quiet .btn { flex: 1 1 100%; }
.sd-quiet .btn .icon { color: #25d366; }
.sd-block > .eyebrow { margin: 6px 2px 10px; }
.sd-setup { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sd-step { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 12px; background: var(--surface-2); font-size: 13.5px; color: var(--text-2); }
.sd-step .icon { flex: none; width: 17px; height: 17px; color: var(--text-3); }
.sd-step.done { color: var(--text); }
.sd-step.done .icon { color: var(--ok); }
.sd-owner { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; padding: 12px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); }
.sd-owner .avatar { width: 42px; height: 42px; font-size: 16px; }
.sd-owner .name { font-weight: 600; }
.sd-owner .pill { margin-top: 6px; }
.sd-owner .icon-btn { flex: none; width: 42px; height: 42px; border-radius: 13px; background: var(--surface-3); }
.sd-owner .icon-btn.wa { color: #25d366; }
.sd .notice { margin-top: 12px; }
.old-links { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line-2); }
.old-links > * + * { margin-top: 4px; }

/* Sign-in details to hand over */
.cred { display: grid; gap: 8px; }
.cred-row { display: flex; align-items: center; gap: 10px; padding: 12px 12px 12px 14px; border-radius: 14px; background: var(--surface-2); border: 1px solid var(--line); }
[dir='rtl'] .cred-row { padding: 12px 14px 12px 12px; }
.cred-row .v { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.cred-row.link .v { font-size: 13px; font-weight: 500; color: var(--text-2); }
[dir='rtl'] .cred-row .v { text-align: right; }
.cred-row.secret { border-color: var(--brand-line); background: linear-gradient(160deg, var(--brand-soft), var(--surface-2) 70%); }
.cred-row.secret .v { font: 600 23px/1.3 ui-monospace, 'SF Mono', Menlo, Consolas, monospace; letter-spacing: .04em; }
.cred-row .icon-btn { flex: none; width: 40px; height: 40px; border-radius: 12px; }
.cred-intro { margin-bottom: 14px; }

/* The platform sheet ends with signing out: a quiet row, in the danger colour. */
.platform-out { display: flex; align-items: center; gap: 12px; width: 100%; margin-top: 22px; padding: 10px 12px; border-radius: 16px; background: none; border: 1px solid var(--line); color: var(--danger); font-size: 15px; font-weight: 500; text-align: start; cursor: pointer; transition: background-color .2s, border-color .2s; }
.platform-out:hover { background: color-mix(in srgb, var(--danger) 9%, transparent); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.platform-out .tile { flex: none; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: color-mix(in srgb, var(--danger) 12%, transparent); }
.platform-out .icon { width: 18px; height: 18px; }

.admin .s-head { flex-wrap: wrap; }
.admin-empty { margin-top: 24px; }

/* On a phone, "new salon" floats in reach while the list scrolls. */
@media (max-width: 699px) {
  .admin .new-salon { position: fixed; z-index: 45; inset-inline-end: 16px; bottom: calc(18px + var(--safe-bottom)); height: 54px; padding: 0 22px 0 18px; border-radius: 18px; font-size: 15px; box-shadow: 0 18px 40px -12px var(--brand-glow), 0 0 0 1px rgb(255 255 255 / .14) inset; animation: fab-in .55s var(--spring) .35s both; }
  [dir='rtl'] .admin .new-salon { padding: 0 18px 0 22px; }
  .studio.admin .s-page { padding-bottom: calc(100px + var(--safe-bottom)); }
}
@keyframes fab-in { from { opacity: 0; transform: translateY(24px) scale(.9); } }

@media (min-width: 700px) {
  .kpis { grid-template-columns: repeat(4, 1fr); }
  .salon-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1080px) {
  .studio.admin .s-page { max-width: 1120px; }
  /* The bar runs edge to edge (its glass too, once scrolled); its padding puts the
     brand and buttons on the page column's edges (1120px column, 40px gutters). */
  .studio.admin .s-header { max-width: none; margin: 0; padding-inline: max(40px, calc((100% - 1120px) / 2 + 40px)); }
  .studio.admin .salon-grid { grid-template-columns: repeat(3, 1fr); }
  .trend-card { padding: 26px 26px 14px; }
  .layout-toggle { display: flex; }

  /* The list layout: one 64px row per salon, its pieces in columns. */
  .studio.admin .salon-grid.list { --cols: 40px minmax(0, 1.6fr) 150px minmax(0, 1.25fr) minmax(0, 1fr) 116px; grid-template-columns: 1fr; gap: 6px; }
  .salon-grid.list .salon-list-head { display: grid; grid-template-columns: var(--cols); gap: 18px; padding: 0 18px 2px; font-size: 12px; font-weight: 500; color: var(--text-3); }
  .salon-grid.list .salon-list-head span:last-child { text-align: end; }
  .salon-grid.list .salon-card { grid-template-columns: var(--cols); gap: 18px; min-height: 64px; padding: 10px 18px; border-radius: 16px; box-shadow: none; }
  .salon-grid.list .salon-card:hover { transform: none; background: var(--surface-2); box-shadow: none; }
  .salon-grid.list .salon-card > * { grid-row: 1; }
  .salon-grid.list .sc-icon { width: 40px; height: 40px; border-radius: 12px; }
  .salon-grid.list .live-dot { width: 12px; height: 12px; }
  .salon-grid.list .salon-card .name { font-size: 15px; }
  .salon-grid.list .sc-setup { display: flex; grid-column: 3; }
  .salon-grid.list .sc-setup b { display: block; }
  .salon-grid.list .sc-line { display: contents; }
  .salon-grid.list .sc-book { grid-column: 4; grid-row: 1; max-width: none; color: var(--text); font-size: 13px; }
  .salon-grid.list .sc-seen { grid-column: 5; grid-row: 1; font-size: 13px; }
  /* The column is headed "last seen": the row shows the time alone. */
  .salon-grid.list .sc-who, .salon-grid.list .sc-sep { display: none; }
  .salon-grid.list .sc-when { margin-inline-start: 0; }
  /* A temporary password sits under the time, so the column never runs into the status. */
  .salon-grid.list .sc-seen { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 2px 6px; }
  .salon-grid.list .sc-seen .pill.tiny { grid-column: 2; justify-self: start; max-width: 100%; margin: 0; }
  .salon-grid.list .sc-status { grid-column: 6; justify-self: end; }
}

/* On a wide screen a salon opens in a drawer at the inline end, beside the list. */
.sheet.drawer { --drawer-out: calc(100% + 24px); }
[dir='rtl'] .sheet.drawer { --drawer-out: calc(-100% - 24px); }
@media (min-width: 1080px) {
  .sheet-backdrop:has(> .sheet.drawer) { justify-content: flex-end; align-items: stretch; padding: 12px; background: rgb(3 0 20 / .4); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .sheet.drawer { width: 520px; max-width: 520px; height: auto; max-height: none; border-radius: 26px; box-shadow: -30px 0 80px -30px rgb(0 0 0 / .8); animation: drawer-in .45s var(--ease-out); }
  .sheet.drawer.closing { transform: translateX(var(--drawer-out)); opacity: 1; transition: transform .25s var(--ease-out); }
}
@keyframes drawer-in { from { transform: translateX(var(--drawer-out)); } }

/* ==========================================================================
   Effects
   ========================================================================== */
/* Headings and figures are solid ink: the light is at the edges, never painted into text. */

/* Page changes: the old page lifts away, the new one rises in; the tab bar stays put. */
::view-transition-old(root) { animation: vt-out .2s ease both; }
::view-transition-new(root) { animation: vt-in .45s var(--ease-out) both; }
::view-transition-group(tab-pill), ::view-transition-group(side-pill) { animation-duration: .45s; animation-timing-function: var(--spring); }
@keyframes vt-out { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(14px); } }
/* Between studio tabs the page slides the way the tabs go: towards the start for a
   later tab, back for an earlier one (mirrored in Arabic). */
html[data-nav='forward']::view-transition-old(root) { animation: vt-out-start .22s ease both; }
html[data-nav='forward']::view-transition-new(root) { animation: vt-in-end .5s var(--ease-out) both; }
html[data-nav='back']::view-transition-old(root) { animation: vt-out-end .22s ease both; }
html[data-nav='back']::view-transition-new(root) { animation: vt-in-start .5s var(--ease-out) both; }
@keyframes vt-out-start { to { opacity: 0; transform: translateX(-28px); } }
@keyframes vt-out-end { to { opacity: 0; transform: translateX(28px); } }
@keyframes vt-in-end { from { opacity: 0; transform: translateX(44px); } }
@keyframes vt-in-start { from { opacity: 0; transform: translateX(-44px); } }
html[dir='rtl'][data-nav='forward']::view-transition-old(root) { animation-name: vt-out-end; }
html[dir='rtl'][data-nav='forward']::view-transition-new(root) { animation-name: vt-in-start; }
html[dir='rtl'][data-nav='back']::view-transition-old(root) { animation-name: vt-out-start; }
html[dir='rtl'][data-nav='back']::view-transition-new(root) { animation-name: vt-in-end; }

@keyframes float { 50% { transform: translateY(-9px); } }

/* Interactive cards lift a little. */
.type-card:hover, .palette:hover { transform: translateY(-3px); }

/* Team cards tilt towards the mouse, with a moving sheen. */
.member.tilt { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .3s var(--ease-out); will-change: transform; }
.member .shine { position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .3s;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 0%), rgb(255 255 255 / .22), transparent 55%); }
.member.tilt:hover .shine { opacity: 1; }
.member:hover .portrait { box-shadow: 0 24px 50px -20px var(--brand-glow); }

/* The finished portrait: a glow as it arrives, and a burst of little stars. */
.photo-frame { position: relative; }
.portrait.finished { border-radius: 26px; box-shadow: 0 30px 60px -30px rgb(0 0 0 / .9), 0 0 0 1px var(--line-2); }
.portrait.finished.revealing { animation: halo 1.8s var(--ease-out); }
@keyframes halo { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--glow-1) 90%, transparent), 0 0 0 1px var(--line-2); } 100% { box-shadow: 0 0 0 26px color-mix(in srgb, var(--blue) 0%, transparent), 0 0 0 1px var(--line-2); } }
.sparkle-burst { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.sparkle-burst i {
  position: absolute; left: 50%; top: 50%; width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  background: radial-gradient(circle, #fff 0 22%, var(--glow-1-soft) 48%, var(--blue) 70%);
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: burst 1.2s var(--ease-out) var(--d) both;
}
@keyframes burst {
  0% { transform: translate(0, 0) scale(0) rotate(0deg); opacity: 1; }
  70% { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1) rotate(200deg); opacity: 0; }
}

/* Sidebar highlight slides too. */
.s-side a.nav { isolation: isolate; }
.s-side a.nav .nav-pill { border-radius: 14px; view-transition-name: side-pill; }
/* Its bulb: a short lit tube at the start edge. */
.s-side a.nav .nav-pill::after { content: ''; position: absolute; inset-inline-start: 0; top: 50%; width: 3px; height: 14px; margin-top: -7px; border-radius: 3px; background: var(--light-hi); box-shadow: 0 0 10px var(--light-glow), 0 0 3px var(--light); }



/* ==========================================================================
   Public salon page: the salon's night
   ========================================================================== */
.page { max-width: 640px; margin: 0 auto; padding: 16px 16px calc(24px + var(--safe-bottom)); }
.p-page { min-height: 100dvh; background: var(--bg); }
[data-theme='public'] .avatar-stack .avatar { border-color: var(--surface); }

/* Hero: aurora in the salon's colours, its app icon in a ring of mirror lights. Its
   colours come from --hero-* (night, day, or over the salon's cover photo). The
   layers move at different depths: with the scroll (where the browser can tie
   animations to it) and, with a mouse, a little with the pointer (--px, --py). */
[data-theme='public'] {
  --hero-bg: var(--night); --hero-ink: #fff; --hero-ink-2: rgb(255 255 255 / .72);
  --hero-glass: rgb(255 255 255 / .08); --hero-glass-line: rgb(255 255 255 / .14);
  --hero-light: var(--accent-lift); --hero-blend: screen;
  --hero-title: linear-gradient(180deg, #fff 40%, color-mix(in srgb, var(--accent-lift), #fff 35%));
}
[data-theme='public'][data-page='day'] {
  --hero-bg: var(--primary); --hero-ink: var(--on-primary); --hero-ink-2: color-mix(in srgb, var(--on-primary) 76%, transparent);
  --hero-glass: color-mix(in srgb, var(--on-primary) 12%, transparent); --hero-glass-line: color-mix(in srgb, var(--on-primary) 22%, transparent);
  --hero-light: var(--accent); --hero-blend: normal;
  --hero-title: linear-gradient(var(--on-primary), var(--on-primary));
}
/* Installed on an iPhone, the status bar is see-through with white text; by day a band
   of the main colour stays under it, so the clock reads over the light bar and pages.
   Zero high everywhere else (in the browser, and with the opaque 'default' bar). */
[data-theme='public'][data-page='day'] body::before {
  content: ''; position: fixed; z-index: 450; top: 0; inset-inline: 0; height: var(--safe-top);
  background: var(--primary); pointer-events: none;
}
.p-hero.has-cover {
  --hero-ink: #fff; --hero-ink-2: rgb(255 255 255 / .82); --hero-glass: rgb(255 255 255 / .12); --hero-glass-line: rgb(255 255 255 / .22);
  --hero-light: var(--accent-lift); --hero-title: linear-gradient(180deg, #fff 45%, color-mix(in srgb, var(--accent-lift), #fff 40%));
}
.p-hero { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; padding: calc(14px + var(--safe-top)) 20px 34px; text-align: center; background: var(--hero-bg); color: var(--hero-ink); }
.p-hero .cover { position: absolute; inset: 0; z-index: -4; width: 100%; height: 100%; object-fit: cover; animation: cover-in 1.4s var(--ease-out) both; }
@keyframes cover-in { from { opacity: 0; transform: scale(1.08); } }
/* A scrim keeps text readable over any photo; without one, a vignette gives depth. */
.p-hero.has-cover::before { content: ''; position: absolute; inset: 0; z-index: -2; background: linear-gradient(180deg, rgb(0 0 0 / .5), rgb(0 0 0 / .28) 38%, rgb(0 0 0 / .62)); }
.p-hero:not(.has-cover)::before { content: ''; position: absolute; inset: 0; z-index: -2; pointer-events: none; background: radial-gradient(120% 90% at 50% 0%, transparent 45%, color-mix(in srgb, var(--night) 85%, transparent)); }
[data-page='day'] .p-hero:not(.has-cover)::before { background: radial-gradient(120% 90% at 50% 0%, transparent 50%, color-mix(in srgb, var(--primary), #000 32%)); opacity: .75; }
.p-hero .aurora { position: absolute; inset: -30% -20% 0; z-index: -3; filter: blur(64px) saturate(1.25); pointer-events: none; }
.p-hero.has-cover .aurora { opacity: .4; }
.p-hero .aurora i { position: absolute; width: 62%; aspect-ratio: 1; border-radius: 50%; mix-blend-mode: var(--hero-blend); animation: aurora 20s ease-in-out infinite alternate; transition: translate 1.4s var(--ease-out); }
.p-hero .aurora i:nth-child(1) { top: 4%; left: -8%; background: var(--primary-lift); opacity: .45; translate: calc(var(--px, 0) * -70px) calc(var(--py, 0) * -40px); }
.p-hero .aurora i:nth-child(2) { top: 14%; right: -14%; background: var(--hero-light); opacity: .42; animation-duration: 26s; animation-direction: alternate-reverse; translate: calc(var(--px, 0) * -130px) calc(var(--py, 0) * -70px); }
.p-hero .aurora i:nth-child(3) { bottom: -18%; left: 26%; background: color-mix(in srgb, var(--primary), var(--hero-light) 35%); opacity: .5; animation-duration: 31s; translate: calc(var(--px, 0) * -40px) calc(var(--py, 0) * -24px); }
[data-page='day'] .p-hero:not(.has-cover) .aurora i { opacity: .45; }
@keyframes aurora { to { transform: translate(9%, 7%) scale(1.18) rotate(24deg); } }
/* At night the hero melts into the page; by day the page rises over it as a sheet. */
.p-hero::after { content: ''; position: absolute; inset: auto 0 0; height: 46%; z-index: -1; background: linear-gradient(transparent, var(--bg)); }
[data-page='day'] .p-hero { padding-bottom: 58px; }
[data-page='day'] .p-hero::after { display: none; }
/* The sheet runs the full width, so no page colour shows beside it on wide screens. */
.p-sheet { position: relative; }
[data-page='day'] .p-sheet { margin-top: -28px; padding-top: 22px; background: var(--bg); border-radius: 28px 28px 0 0; box-shadow: 0 -12px 30px -18px rgb(0 0 0 / .35); }
.p-top { position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 44px; }
.p-top-end { display: flex; align-items: center; gap: 8px; }
/* On a wide screen the hero's top reads as a site header: the sections in a glass pill. */
.p-top-nav { display: none; }
@media (min-width: 1024px) {
  .p-top-nav { position: absolute; top: 50%; left: 50%; translate: -50% -50%; display: flex; gap: 2px; padding: 4px; border-radius: 99px; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
  .p-top-nav a { display: inline-grid; place-items: center; height: 34px; padding: 0 16px; border-radius: 99px; color: var(--hero-ink-2); font-size: 14px; font-weight: 500; white-space: nowrap; transition: background-color .2s, color .2s; }
  .p-top-nav a:hover { background: color-mix(in srgb, var(--hero-ink) 12%, transparent); color: var(--hero-ink); }
}
.p-glass-btn { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 14px; border-radius: 999px; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); color: var(--hero-ink); font-size: 13.5px; font-weight: 500; white-space: nowrap; flex: none; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); cursor: pointer; transition: background-color .2s; }
.p-glass-btn:hover { background: color-mix(in srgb, var(--hero-ink) 16%, transparent); }
.p-glass-btn .icon { width: 18px; height: 18px; }
.p-glass-btn.round { width: 40px; padding: 0; justify-content: center; }
/* The install button carries the salon's own app icon. */
.p-glass-icon { width: 24px; height: 24px; margin-inline-start: -7px; border-radius: 7px; box-shadow: 0 0 0 1px rgb(255 255 255 / .2); }
/* The owner's own page adds "manage" to install, share and language: on a phone the
   labelled pills don't fit, so they become round icons (each keeps its aria-label). */
@media (max-width: 479px) {
  .p-top:has(> a.p-glass-btn) :is(a.p-glass-btn, .p-install) { width: 40px; padding: 0; justify-content: center; }
  .p-top:has(> a.p-glass-btn) :is(a.p-glass-btn, .p-install) > span { display: none; }
  .p-top:has(> a.p-glass-btn) .p-glass-icon { margin: 0; }
}
.p-hero-content { position: relative; width: 100%; max-width: 560px; margin: 6px auto 0; }
.p-mirror { --ring: 78px; position: relative; width: 168px; height: 168px; margin: 0 auto 14px; display: grid; place-items: center; translate: calc(var(--px, 0) * 22px) calc(var(--py, 0) * 14px); transition: translate 1s var(--ease-out); }
.p-lights { position: absolute; inset: 0; }
.p-lights i { position: absolute; left: 50%; top: 50%; width: 6px; height: 6px; margin: -3px; border-radius: 50%; background: var(--hero-light); box-shadow: 0 0 10px 2px color-mix(in srgb, var(--hero-light) 65%, transparent); transform: rotate(calc(var(--i) * 360deg / var(--n, 18))) translateY(calc(var(--ring) * -1)); animation: mirror-light 2.8s ease-in-out infinite; animation-delay: calc(var(--i) * -.155s); }
@keyframes mirror-light { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
/* The salon's app icon exactly as its launch screen and the home screen show it. */
.p-logo { position: relative; width: 112px; height: 112px; border-radius: 30px; object-fit: cover; box-shadow: 0 0 0 1px rgb(255 255 255 / .2), 0 24px 50px -16px rgb(0 0 0 / .8), 0 0 60px -10px color-mix(in srgb, var(--hero-light) 55%, transparent); animation: pop .8s var(--spring) both; translate: calc(var(--px, 0) * 10px) calc(var(--py, 0) * 8px); transition: translate .8s var(--ease-out); }
.p-hero h1 { font-size: clamp(34px, 9vw, 58px); line-height: 1.15; padding-block: .06em; text-wrap: balance; background: var(--hero-title); -webkit-background-clip: text; background-clip: text; color: transparent; animation: rise .7s var(--ease-out) .1s both; }
.p-about { margin: 8px auto 0; max-width: 42ch; color: var(--hero-ink-2); font-size: 15px; text-wrap: balance; animation: rise .7s var(--ease-out) .18s both; }
.p-status { display: inline-flex; align-items: center; gap: 8px; margin-top: 16px; padding: 7px 14px; border-radius: 999px; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); font-size: 13.5px; animation: rise .7s var(--ease-out) .26s both; }
.p-status .dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--hero-ink-2); }
.p-status.open .dot { background: #4ade80; }
.p-status.open .dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 2px solid #4ade80; animation: ping 2.2s var(--ease-out) infinite; }
.p-actions { display: flex; justify-content: center; gap: 18px; margin-top: 22px; }
.p-action { display: flex; flex-direction: column; align-items: center; gap: 7px; min-width: 56px; padding: 0; background: none; border: 0; color: var(--hero-ink-2); font-size: 12px; cursor: pointer; animation: rise .7s var(--ease-out) both; }
.p-action:nth-child(1) { animation-delay: .32s; } .p-action:nth-child(2) { animation-delay: .38s; } .p-action:nth-child(3) { animation-delay: .44s; } .p-action:nth-child(4) { animation-delay: .5s; }
.p-action .c { display: grid; place-items: center; width: 54px; height: 54px; border-radius: 50%; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); color: var(--hero-ink); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); transition: transform .3s var(--spring), background-color .2s, box-shadow .3s; }
.p-action .icon { width: 22px; height: 22px; }
.p-action:hover .c { background: color-mix(in srgb, var(--hero-ink) 16%, transparent); box-shadow: 0 0 28px -6px color-mix(in srgb, var(--hero-light) 70%, transparent); }
.p-action:active .c { transform: scale(.9); }
/* The hero's own booking button, the paused-booking note and the scroll cue are for
   wide screens; on a phone the book button is pinned to the bottom instead. */
.p-hero-book, .p-hero-note, .p-cue { display: none; }
/* On a phone the hero is compact, so the menu starts on the first screen. */
@media (max-width: 719px) {
  .p-mirror { --ring: 56px; width: 124px; height: 124px; margin-bottom: 10px; }
  .p-logo { width: 84px; height: 84px; border-radius: 24px; }
  .p-hero h1 { font-size: clamp(28px, 8vw, 40px); }
  .p-status { margin-top: 12px; }
  .p-actions { margin-top: 16px; gap: 14px; }
  .p-action .c { width: 48px; height: 48px; }
}

/* Not open yet: the salon's link is a cover, the whole screen in its hero's light. The
   shop's pole in its glass seal with the light off, in a ring of bulbs not lit yet; the
   name, "opening soon" in the light, and how to reach the salon meanwhile. Nothing loops. */
.p-hero.p-soon, [data-page='day'] .p-hero.p-soon { min-height: 100dvh; padding-bottom: calc(22px + var(--safe-bottom)); }
.p-soon::after { display: none; }
.p-soon-in { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; max-width: 520px; margin: 0 auto; padding: 24px 0 36px; }
.p-soon-sign { position: relative; display: grid; place-items: center; width: 196px; height: 196px; margin-bottom: 18px; animation: rise .8s var(--ease-out) both; }
.p-soon-seal { position: relative; width: 128px; height: 128px; }
/* Switched off: the stripes are there, unlit. */
.p-soon-seal .ps-tube { filter: saturate(.55) brightness(.78); }
.p-soon-bulbs { --rd: 90px; --bs: 7px; }
.p-soon-bulbs i { background: color-mix(in srgb, var(--hero-ink) 18%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--hero-ink) 10%, transparent); }
.p-soon-id { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.p-soon-logo { width: 60px; height: 60px; border-radius: 17px; box-shadow: 0 0 0 1px rgb(255 255 255 / .2), 0 16px 30px -12px rgb(0 0 0 / .7); animation: rise .7s var(--ease-out) .08s both; }
.p-soon-k { display: inline-flex; align-items: center; gap: 12px; margin-top: 14px; font-size: 15px; font-weight: 600; color: var(--hero-light); text-shadow: 0 0 18px color-mix(in srgb, var(--hero-light) 55%, transparent); animation: rise .7s var(--ease-out) .2s both; }
.p-soon-k::before, .p-soon-k::after { content: ''; width: 26px; height: 1px; background: currentColor; opacity: .55; }
:lang(en) .p-soon-k { text-transform: uppercase; letter-spacing: .18em; font-size: 12.5px; }
.p-soon-sub { margin-top: 10px; max-width: 32ch; color: var(--hero-ink-2); font-size: 15px; line-height: 1.6; text-wrap: balance; animation: rise .7s var(--ease-out) .26s both; }
.p-soon .p-actions { margin-top: 26px; }
.p-soon-owner { display: grid; justify-items: center; gap: 12px; max-width: 360px; margin-top: 30px; padding: 16px 18px; border-radius: 20px; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); animation: rise .7s var(--ease-out) .34s both; }
.p-soon-owner p { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px; line-height: 1.55; color: var(--hero-ink-2); text-align: start; }
.p-soon-owner p .icon { flex: none; width: 16px; height: 16px; margin-top: 3px; }
.p-soon-foot { display: grid; justify-items: center; gap: 12px; font-size: 12.5px; }
.p-soon-foot .legal-links a { color: var(--hero-ink-2); }
.p-soon-foot .p-powered { background: var(--hero-glass); border-color: var(--hero-glass-line); color: var(--hero-ink-2); }
@media (max-width: 719px) {
  .p-soon-sign { width: 168px; height: 168px; }
  .p-soon-seal { width: 108px; height: 108px; }
  .p-soon-bulbs { --rd: 78px; --bs: 6px; }
}

/* The page below the hero. */
/* Gaps come from the grid, so a part that is not shown leaves no space behind. */
.p-main { display: grid; gap: 30px; max-width: 760px; margin: 0 auto; padding: 4px 16px calc(120px + var(--safe-bottom)); }
.p-body { display: grid; gap: 30px; }
.p-col, .p-aside { min-width: 0; }
.p-section { min-width: 0; scroll-margin-top: 112px; }
.p-section + .p-section { margin-top: 30px; }
.p-head { display: flex; align-items: center; gap: 10px; margin: 0 4px 12px; }
.p-head h2 { font-size: 20px; border-radius: 6px; }
.p-head h2:focus:not(:focus-visible) { outline: none; }
.p-card { border-radius: 22px; background: var(--pane-edge), var(--surface); border: 1px solid var(--line); box-shadow: var(--depth-1); }
.p-empty { display: grid; justify-items: center; gap: 12px; padding: 30px 22px; text-align: center; color: var(--text-2); }
.p-empty .ic { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); }
.p-fail .p-fail-ic { display: inline-grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.p-fail .p-fail-ic .icon { width: 26px; height: 26px; }
.p-fail p { max-width: 34ch; margin-inline: auto; color: var(--text-2); }

/* This device's upcoming visits: tickets that open their own pages. The space opens
   smoothly once they have loaded. */
.p-ticket-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .6s var(--ease-out); }
.p-ticket-wrap.in { grid-template-rows: 1fr; }
.p-ticket-clip { min-height: 0; overflow: hidden; }
.p-ticket-body { padding-bottom: 30px; }
.p-tickets { display: grid; gap: 10px; }
.p-ticket { display: flex; align-items: center; gap: 14px; padding: 12px; padding-inline: 14px 12px; border-radius: 22px; background: var(--surface); border: 1px solid var(--line); box-shadow: inset 3px 0 0 var(--brand), var(--shadow); color: var(--text); transition: border-color .25s, transform .3s var(--spring); }
[dir='rtl'] .p-ticket { box-shadow: inset -3px 0 0 var(--brand), var(--shadow); }
.p-ticket:hover { border-color: var(--brand-line); }
.p-ticket:active { transform: scale(.98); }
.p-ticket-date { flex: none; display: grid; justify-items: center; align-content: center; width: 58px; height: 64px; border-radius: 16px; background: var(--brand-soft); line-height: 1.15; text-align: center; }
.p-ticket-date small { font-size: 10.5px; color: var(--text-2); }
.p-ticket-date b { font-size: 22px; font-variant-numeric: tabular-nums; }
.p-ticket .n { display: flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 600; line-height: 1.35; }
.p-ticket .n .e { display: inline-flex; color: var(--brand); }
.p-ticket .n .e .icon { width: 16px; height: 16px; }
.p-ticket .m { margin-top: 2px; font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.p-ticket .pill { height: 24px; margin-top: 7px; padding: 0 10px; font-size: 11.5px; }
.p-ticket > .icon { flex: none; width: 17px; height: 17px; }

/* Services: glass cards; the price in the salon's light. */
.p-services { display: grid; gap: 10px; }
.p-svc { position: relative; overflow: hidden; isolation: isolate; display: flex; align-items: flex-start; gap: 14px; width: 100%; padding: 16px; border-radius: 22px; background: var(--pane-edge), linear-gradient(160deg, color-mix(in srgb, var(--text) 5%, transparent), transparent 55%), var(--surface); border: 1px solid var(--line); box-shadow: var(--depth-1); color: var(--text); text-align: start; font: inherit; }
[dir='rtl'] .p-svc { background: var(--pane-edge), linear-gradient(200deg, color-mix(in srgb, var(--text) 5%, transparent), transparent 55%), var(--surface); }
button.p-svc { cursor: pointer; transition: transform .3s var(--spring), border-color .25s, box-shadow .3s; }
@media (hover: hover) { button.p-svc:hover { border-color: color-mix(in srgb, var(--brand) 40%, transparent); box-shadow: var(--shadow), 0 18px 40px -22px color-mix(in srgb, var(--brand) 60%, transparent); } }
button.p-svc:active { transform: scale(.98); }
/* A mirror glint on hover. */
button.p-svc::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(105deg, transparent 35%, color-mix(in srgb, var(--text) 7%, transparent) 47%, transparent 60%); transform: translateX(-120%); transition: transform .9s var(--ease-out); }
@media (hover: hover) { button.p-svc:hover::after { transform: translateX(120%); } }
.p-svc-e { flex: none; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; color: var(--brand); background: radial-gradient(circle at 30% 25%, color-mix(in srgb, var(--brand) 24%, transparent), transparent 70%), var(--surface-2); }
.p-svc-e { box-shadow: inset 0 1px 0 var(--rim-hi), inset 0 0 0 1px var(--line); }
.p-svc-e .icon { width: 24px; height: 24px; filter: var(--glyph-glow); }
.p-svc .n { font-size: 16px; font-weight: 600; line-height: 1.4; }
.p-svc .d { margin-top: 2px; font-size: 13px; line-height: 1.55; color: var(--text-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.p-svc .m { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 8px; }
.p-svc .chip { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 99px; background: var(--surface-2); color: var(--text-2); font-size: 12px; }
.p-svc .chip .icon { width: 13px; height: 13px; }
.p-svc .avatar-stack .avatar { width: 24px; height: 24px; font-size: 10px; }
.p-svc-who { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-2); }
.p-svc-who .avatar { width: 22px; height: 22px; font-size: 10px; }
/* The price on one line, "from" before it, all prices on the same baseline. */
.p-svc-p, .p-svc-price { flex: none; display: flex; align-items: baseline; gap: 5px; }
.p-svc-p { padding-top: 2px; }
.p-svc-p small { font-size: 12px; color: var(--text-2); }
.p-svc-p b { font-size: 17px; color: var(--brand); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* On the page, the price heads the card's end and a "Book" pill sits under it, level
   with the length: every card says it books, on a touch screen too. (The booking
   sheet's own cards keep their arrow.) */
.p-main .p-svc-p { align-self: stretch; flex-direction: column; align-items: flex-end; justify-content: space-between; gap: 8px; }
.p-main .p-svc-go { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 12px; border-radius: 99px; background: var(--brand-soft); color: var(--brand); font-size: 12.5px; font-weight: 600; white-space: nowrap; transition: background-color .25s, color .25s; }
.p-main .p-svc-go .icon { width: 14px; height: 14px; }
button.p-svc:focus-visible .p-svc-go { background: var(--brand); color: var(--on-brand); }
@media (hover: hover) { button.p-svc:hover .p-svc-go { background: var(--brand); color: var(--on-brand); } }
/* A service nobody on the team does: on the menu, but quiet and not bookable. */
.p-svc.off .p-svc-e { color: var(--text-3); background: var(--surface-2); }
.p-svc.off .p-svc-p b { color: var(--text-3); }
.p-svc-off { display: inline-flex; align-items: center; height: 24px; padding: 0 9px; border-radius: 99px; border: 1px dashed var(--line-2); color: var(--text-2); font-size: 12px; }

/* Team: portraits in a carousel, name on the glass; tapping one books with them. */
.scroller.p-team { gap: 12px; padding-bottom: 10px; }
.p-member { position: relative; display: block; width: min(40vw, 220px); padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: start; }
button.p-member { cursor: pointer; }
button.p-member:focus-visible { outline: none; }
button.p-member:focus-visible .portrait { outline: 2px solid var(--light); outline-offset: 3px; }
.p-member .portrait { border-radius: 24px; box-shadow: 0 0 0 1px var(--line-2), 0 24px 44px -24px rgb(0 0 0 / .9); }
.p-member-book { position: absolute; z-index: 2; top: 10px; inset-inline-end: 10px; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: rgb(0 0 0 / .32); border: 1px solid rgb(255 255 255 / .24); color: #fff; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); transition: background-color .25s, color .25s, transform .3s var(--spring); }
.p-member-book .icon { width: 16px; height: 16px; }
button.p-member:hover .p-member-book { background: var(--brand); border-color: transparent; color: var(--on-brand); transform: scale(1.08); }
/* Two people side by side; one person as a card of its own. */
.p-team.few { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.p-team.few .p-member { width: auto; }
.p-member.solo { display: flex; align-items: center; gap: 16px; width: 100%; padding: 12px; border-radius: 24px; background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow); transition: border-color .25s, transform .3s var(--spring); }
button.p-member.solo:hover { border-color: var(--brand-line); }
button.p-member.solo:active { transform: scale(.98); }
button.p-member.solo:focus-visible { outline: 2px solid var(--light); outline-offset: 2px; }
.p-member.solo .portrait { flex: none; width: 96px; border-radius: 18px; box-shadow: 0 0 0 1px var(--line-2); }
.p-member.solo .n { font-size: 17px; font-weight: 700; line-height: 1.3; }
.p-member.solo .r { font-size: 13px; color: var(--text-2); }
.p-solo-cta { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; height: 34px; padding: 0 14px; border-radius: 99px; background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--text); font-size: 13.5px; font-weight: 600; }
.p-solo-cta .icon { width: 16px; height: 16px; color: var(--brand); }
button.p-member.solo:hover .p-solo-cta { background: var(--brand); color: var(--on-brand); }
button.p-member.solo:hover .p-solo-cta .icon { color: inherit; }
/* Previous / next for mouse users, beside the team's title. */
.p-team-nav { display: none; }
@media (hover: hover) and (pointer: fine) {
  .p-team-nav { display: flex; gap: 6px; margin-inline-start: auto; }
  .p-team-nav[hidden] { display: none; }
  .p-nav-btn { width: 36px; height: 36px; border-radius: 50%; background: var(--surface); }
  .p-nav-btn .icon { width: 17px; height: 17px; }
  .p-nav-btn:disabled { opacity: .35; cursor: default; }
}
.p-member .portrait::after { content: ''; position: absolute; inset: 50% 0 0; background: linear-gradient(transparent, rgb(0 0 0 / .78)); pointer-events: none; }
.p-member .portrait.tilt { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .3s var(--ease-out); }
.p-member .info { position: absolute; inset: auto 12px 12px; z-index: 1; color: #fff; text-align: start; }
.p-member .n { font-size: 16px; font-weight: 700; line-height: 1.25; }
.p-member .r { font-size: 12.5px; opacity: .78; }

/* Hours: days with the same hours on one line; today's line lit, its day as a bar on a
   24-hour line with a tick at now. */
.p-hours { padding: 8px; }
.p-hour { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; column-gap: 12px; row-gap: 10px; padding: 12px; border-radius: 16px; font-size: 14.5px; line-height: 1.5; }
.p-hour + .p-hour { margin-top: 2px; }
.p-hour .d { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }
.p-hour .v { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: end; font-variant-numeric: tabular-nums; }
.p-hour .v .r { white-space: nowrap; }
.p-hour.off .d, .p-hour.off .v { color: var(--text-3); }
.p-hour.today { background: linear-gradient(90deg, color-mix(in srgb, var(--brand) 14%, transparent), transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 28%, transparent); font-weight: 600; }
[dir='rtl'] .p-hour.today { background: linear-gradient(270deg, color-mix(in srgb, var(--brand) 14%, transparent), transparent); }
.p-today { height: 20px; padding: 0 8px; border-radius: 99px; display: inline-grid; place-items: center; background: var(--brand); color: var(--on-brand); font-size: 11px; font-weight: 600; }
.p-track { grid-column: 1 / -1; position: relative; height: 6px; border-radius: 99px; background: var(--surface-2); }
.p-seg { position: absolute; top: 0; bottom: 0; border-radius: 99px; background: color-mix(in srgb, var(--brand) 50%, var(--surface-3)); transform-origin: right center; }
[dir='ltr'] .p-seg { transform-origin: left center; }
.p-hours.in .p-seg { animation: p-grow 1s var(--ease-out) .15s both; }
@keyframes p-grow { from { transform: scaleX(0); opacity: 0; } }
.p-hour.today .p-seg { background: var(--grad); box-shadow: 0 0 14px var(--brand-glow); }
.p-now { position: absolute; top: 50%; width: 2px; height: 14px; margin-top: -7px; margin-inline-start: -1px; border-radius: 1px; background: var(--text); box-shadow: 0 0 0 2px var(--surface); }
.p-track-cap { grid-column: 1 / -1; display: flex; justify-content: space-between; margin-top: -2px; font-size: 11px; font-weight: 400; color: var(--text-3); }

/* Contact */
.p-contact { padding: 4px; }
.p-line { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 16px; transition: background-color .2s; }
.p-line:hover { background: var(--surface-2); }
.p-line + .p-line { margin-top: 2px; }
.p-line .ic { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 13px; background: var(--grad-soft); color: var(--brand); }
.p-line .ic .icon { width: 19px; height: 19px; }
.p-line > .icon { width: 17px; height: 17px; flex: none; }
/* Footer: the salon signs off; the platform is a small, quiet pill. */
.p-foot { display: grid; gap: 16px; justify-items: center; margin-top: 10px; padding-top: 30px; border-top: 1px solid var(--line); font-size: 13px; text-align: center; }
.p-foot a { color: var(--text-2); }
.p-foot-brand { display: flex; align-items: center; gap: 12px; text-align: start; }
.p-foot-mark { flex: none; width: 42px; height: 42px; border-radius: 12px; box-shadow: 0 0 0 1px var(--line-2); }
.p-foot-brand b { display: block; font-size: 15.5px; line-height: 1.35; }
.p-foot-brand span { display: block; font-size: 12.5px; color: var(--text-2); }
.p-powered { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px; border-radius: 99px; background: var(--surface); border: 1px solid var(--line); color: var(--text-2); font-size: 12px; }
.p-powered .icon { width: 13px; height: 13px; color: var(--brand); }
.p-foot .p-owner { font-size: 12px; text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; }
/* Links to the privacy policy and the terms (server pages). */
.legal-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 16px; font-size: 13px; }
.legal-links a { color: var(--text-2); text-decoration: none; }
.legal-links a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.legal-links.in-sheet { margin-top: 18px; }
.consent { margin: 14px 2px 0; font-size: 12.5px; line-height: 1.7; color: var(--text-2); }
.consent a { color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

/* The glass bar that arrives once the hero is gone: the salon's name and tabs for its
   sections, one highlight sliding to the section being read. The book button stays
   pinned below on a phone. */
.p-bar { position: fixed; z-index: 40; top: 0; inset-inline: 0; padding: calc(8px + var(--safe-top)) 12px 8px; background: var(--glass); border-bottom: 1px solid var(--line); backdrop-filter: blur(20px) saturate(1.5); -webkit-backdrop-filter: blur(20px) saturate(1.5); transform: translateY(-110%); transition: transform .45s var(--ease-out); }
.p-bar.on { transform: none; }
.p-bar-inner { max-width: 760px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: center; column-gap: 10px; }
.p-bar-id { flex: 1 0 100%; min-width: 0; display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; }
.p-bar-id > span { min-width: 0; }
.p-bar-logo { flex: none; width: 30px; height: 30px; border-radius: 9px; box-shadow: 0 0 0 1px var(--line-2); }
.p-bar-book { display: none; }
.p-tabs { position: relative; flex-basis: 100%; display: flex; gap: 2px; margin: 8px -12px 0; padding-inline: 12px; overflow-x: auto; scrollbar-width: none; }
.p-tabs::-webkit-scrollbar { display: none; }
.p-tabs a { position: relative; z-index: 1; flex: none; display: inline-grid; place-items: center; height: 32px; padding: 0 14px; border-radius: 99px; color: var(--text-2); font-size: 13px; font-weight: 500; white-space: nowrap; transition: color .25s; }
.p-tabs a:hover, .p-tabs a.on { color: var(--text); }
.p-tabs a:focus-visible { outline-offset: -2px; }
.p-tabs-ind { position: absolute; z-index: 0; top: 0; left: 0; width: 0; height: 32px; border-radius: 99px; background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand-line); opacity: 0; pointer-events: none; transition: transform .45s var(--ease-out), width .45s var(--ease-out), opacity .3s; }
.p-tabs-ind.on { opacity: 1; }
/* On a phone the bar is one row: the salon's icon (its name kept for screen readers),
   then the tabs, which scroll to the screen's edge when they don't fit. */
@media (max-width: 479px) {
  .p-bar-inner { flex-wrap: nowrap; }
  .p-bar-id { flex: none; }
  .p-bar-id > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .p-tabs { flex: 1; flex-basis: auto; margin: 0; margin-inline-end: -12px; padding-inline: 0 12px; }
  .p-tabs a, .p-tabs-ind { height: 40px; }
}
/* Tabs that scroll fade out at whichever edge has more (beside the icon, at the screen's edge). */
@supports (animation-timeline: scroll()) {
  @media (max-width: 479px) {
    .p-tabs {
      --fade-dir: 90deg;
      -webkit-mask-image: linear-gradient(var(--fade-dir), transparent, #000 var(--fade-s), #000 calc(100% - var(--fade-e)), transparent);
      mask-image: linear-gradient(var(--fade-dir), transparent, #000 var(--fade-s), #000 calc(100% - var(--fade-e)), transparent);
      animation: strip-edges linear both; animation-timeline: scroll(self inline);
    }
    [dir='rtl'] .p-tabs { --fade-dir: 270deg; }
  }
}
.p-cta { position: fixed; z-index: 40; bottom: 0; inset-inline: 0; padding: 14px 16px calc(14px + var(--safe-bottom)); background: linear-gradient(to top, var(--bg) 45%, transparent); pointer-events: none; }
.p-cta-inner { max-width: 520px; margin: 0 auto; pointer-events: auto; }
.p-book { height: 58px; font-size: 17px; box-shadow: inset 0 1px 0 rgb(255 255 255 / .35), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 26px -6px var(--light-glow), 0 18px 44px -14px color-mix(in srgb, var(--brand) 75%, transparent); }
/* Booking paused: a calm glass note with a way to reach the salon instead. */
.p-cta-note { display: flex; align-items: center; gap: 12px; padding: 12px; padding-inline: 14px 12px; border-radius: 20px; background: var(--glass); border: 1px solid var(--line-2); backdrop-filter: blur(20px) saturate(1.4); -webkit-backdrop-filter: blur(20px) saturate(1.4); box-shadow: var(--shadow-lg); color: var(--text-2); font-size: 14px; line-height: 1.5; white-space: normal; }
.p-cta-note > .icon { flex: none; width: 20px; height: 20px; color: var(--brand); }
.p-cta-note .btn { flex: none; }

/* Installing on an iPhone: the home screen with the salon's icon, then the taps,
   each with the glyph Safari shows (its share button is blue). */
.p-ios { display: grid; gap: 16px; padding-bottom: 6px; }
.p-ios-stage { display: grid; justify-items: center; padding-top: 4px; }
.p-ios-sub { max-width: 34ch; margin-inline: auto; text-align: center; color: var(--text-2); font-size: 14.5px; line-height: 1.6; }
.p-steps { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.p-step { display: flex; align-items: center; gap: 12px; padding: 12px; padding-inline: 12px 14px; border-radius: 18px; background: var(--surface-2); border: 1px solid var(--line); font-size: 14.5px; line-height: 1.5; }
.p-step-n { flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); font-size: 13px; font-weight: 700; }
.p-step-g { flex: none; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: var(--surface-3); color: #4c9dff; }
.p-step-g .icon { width: 20px; height: 20px; }
.p-plus { display: grid; place-items: center; width: 21px; height: 21px; border-radius: 6px; border: 1.7px solid currentColor; }
.p-plus .icon { width: 13px; height: 13px; }
.p-step-g .p-step-icon { width: 38px; height: 38px; border-radius: 11px; }

/* Things drift up into place as they scroll into view. */
.reveal { opacity: 0; transform: translateY(26px) scale(.985); transition: opacity .75s var(--ease-out), transform .9s var(--ease-out); transition-delay: calc(var(--i, 0) * 70ms); }
.reveal.in { opacity: 1; transform: none; }

@media (min-width: 720px) {
  .p-services { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* An odd last service takes the whole row rather than leaving a hole beside it. */
  .p-services > .p-svc:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .p-hero { padding-bottom: 54px; }
  .p-member { width: 210px; }
  .p-team.few { grid-template-columns: repeat(2, 220px); }
  /* One person: a card of a portrait and a name, not a wide empty bar. */
  .p-member.solo { width: auto; max-width: 420px; }
}
/* A wide screen gets a website: a full first screen with its own booking button, then
   the menu and team beside the hours and contact card, which stay in view. */
@media (min-width: 1024px) {
  .p-hero { min-height: clamp(480px, 68vh, 720px); padding: calc(18px + var(--safe-top)) 32px 72px; }
  [data-page='day'] .p-hero { padding-bottom: 92px; }
  .p-top { width: 100%; max-width: 1180px; margin-inline: auto; }
  .p-hero-content { max-width: 760px; margin-block: auto; padding-top: 8px; }
  .p-mirror { --ring: 94px; width: 204px; height: 204px; margin-bottom: 18px; }
  .p-logo { width: 132px; height: 132px; border-radius: 36px; }
  .p-about { margin-top: 10px; font-size: 17px; }
  .p-hero-book { display: flex; width: fit-content; height: 56px; margin: 28px auto 0; padding: 0 30px; font-size: 17px; box-shadow: inset 0 1px 0 rgb(255 255 255 / .35), inset 0 0 0 1px rgb(255 255 255 / .1), 0 0 0 1px var(--light-line), 0 0 26px -6px var(--light-glow), 0 18px 44px -14px color-mix(in srgb, var(--brand) 75%, transparent); }
  .p-hero-note { display: flex; align-items: center; gap: 10px; width: fit-content; margin: 26px auto 0; padding: 10px 18px; border-radius: 99px; background: var(--hero-glass); border: 1px solid var(--hero-glass-line); color: var(--hero-ink); font-size: 14.5px; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
  .p-hero-note .icon { flex: none; width: 18px; height: 18px; color: var(--hero-light); }
  .p-actions { margin-top: 26px; }
  .p-cue { display: grid; place-items: center; position: absolute; z-index: 2; bottom: 18px; left: 50%; width: 40px; height: 40px; margin-left: -20px; border-radius: 50%; border: 1px solid var(--hero-glass-line); background: var(--hero-glass); color: var(--hero-ink-2); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); animation: cue-bob 2.6s ease-in-out infinite; transition: color .2s; }
  .p-cue:hover { color: var(--hero-ink); }
  .p-cue .icon { width: 18px; height: 18px; }
  [data-page='day'] .p-cue { bottom: 48px; }

  .p-bar { padding-inline: 24px; }
  .p-bar-inner { max-width: 1180px; flex-wrap: nowrap; column-gap: 16px; }
  .p-bar-id { flex: 0 1 auto; }
  .p-tabs { flex: 1; flex-basis: auto; justify-content: center; margin: 0; padding: 0; }
  .p-bar.split .p-tabs a.side { display: none; }
  .p-bar-book { display: inline-flex; flex: none; height: 38px; padding: 0 16px; border-radius: 99px; font-size: 14px; }
  .p-bar-book .icon { width: 17px; height: 17px; }
  .p-cta { display: none; }

  [data-page='day'] .p-sheet { margin-top: -40px; padding-top: 30px; border-radius: 40px 40px 0 0; }
  .p-main { max-width: 820px; padding: 16px 32px 64px; }
  .p-main.split { max-width: 1180px; }
  .p-main.split > .p-body { grid-template-columns: minmax(0, 1fr) 360px; column-gap: 40px; align-items: start; }
  .p-section { scroll-margin-top: 88px; }
}
@media (min-width: 1024px) and (min-height: 760px) {
  .p-main.split .p-aside { position: sticky; top: 84px; }
}
@keyframes cue-bob { 50% { transform: translateY(6px); } }
/* Where supported, the hero's layers move at their own pace as the page scrolls over
   it: the photo drifts slower than the page, the lights turn, the glow rises and the
   content sinks back. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .p-hero-content { animation: hero-sink linear both; animation-timeline: scroll(root); animation-range: 0 70vh; }
    .p-hero .cover { animation: cover-in 1.4s var(--ease-out) both, cover-drift linear both; animation-timeline: auto, scroll(root); animation-range: normal, 0 100vh; }
    .p-hero .aurora { animation: aurora-rise linear both; animation-timeline: scroll(root); animation-range: 0 100vh; }
    .p-lights { animation: lights-turn linear both; animation-timeline: scroll(root); animation-range: 0 80vh; }
    .p-cue { animation: cue-bob 2.6s ease-in-out infinite, cue-out linear both; animation-timeline: auto, scroll(root); animation-range: normal, 0 30vh; }
  }
}
@keyframes hero-sink { to { opacity: .1; transform: translateY(60px) scale(.94); filter: blur(3px); } }
@keyframes cover-drift { to { translate: 0 28%; scale: 1.12; } }
@keyframes aurora-rise { to { translate: 0 -18%; } }
@keyframes lights-turn { to { rotate: 120deg; } }
@keyframes cue-out { to { opacity: 0; visibility: hidden; } }

/* ==========================================================================
   Brand kit controls (owner's brand page)
   ========================================================================== */
.icon-bgs { display: flex; flex-wrap: wrap; gap: 8px; padding-bottom: 2px; }
.bg-dot { width: 16px; height: 16px; border-radius: 5px; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .25); }
.bg-dot.white { background: #fff; }
.bg-dot.primary { background: var(--primary); }
.bg-dot.night { background: var(--night); }
.cover-frame { display: block; width: 100%; aspect-ratio: 16 / 7; padding: 0; border-radius: 22px; overflow: hidden; background: var(--surface); border: 1.5px dashed var(--line-2); cursor: pointer; transition: border-color .2s, transform .3s var(--spring); }
.cover-frame.has { border-style: solid; border-color: var(--line); }
.cover-frame:hover { border-color: var(--brand-line); }
.cover-frame:active { transform: scale(.99); }
.cover-frame img { width: 100%; height: 100%; object-fit: cover; animation: fade .6s ease both; }
/* No cover yet: one frame, and the one button that fills it, inside. */
.cover-empty { height: auto; min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 20px 16px; color: var(--text-2); font-size: 13.5px; text-align: center; cursor: default;
  background: radial-gradient(70% 90% at 50% 0%, color-mix(in srgb, var(--glow-1) 12%, transparent), transparent 70%), var(--surface); }
.cover-empty:hover { border-color: var(--brand-line); }
.cover-empty .tile { width: 52px; height: 52px; border-radius: 16px; }
.cover-empty .tile .icon { width: 26px; height: 26px; }
.cover-empty > span { max-width: 30ch; }
.cover-empty .btn { margin-top: 4px; }

/* Brand page: four groups and a sticky chip bar that jumps between them. */
.brand-nav { position: sticky; z-index: 40; top: calc(62px + var(--safe-top)); margin: -6px -16px 14px; padding: 8px 0 4px; border-bottom: 1px solid transparent; transition: background-color .3s, border-color .3s; }
.brand-nav.stuck { background: var(--glass); border-color: var(--line); backdrop-filter: blur(20px) saturate(1.6); -webkit-backdrop-filter: blur(20px) saturate(1.6); }
/* Pinned together, header and chips read as one glass bar. */
body:has(.brand-nav.stuck) .s-header.scrolled { border-color: transparent; }
.brand-nav .scroller { margin-inline: 0; padding-bottom: 4px; }
.brand-nav .chip-btn { height: 36px; padding: 0 14px; font-size: 13.5px; }
.brand-nav .chip-btn.on { background: var(--grad, var(--brand)); color: var(--on-brand); border-color: transparent; box-shadow: 0 8px 20px -10px var(--brand-glow); }
.brand-group { scroll-margin-top: calc(120px + var(--safe-top)); }
.brand-group + .brand-group { margin-top: 8px; }
/* The floating phone: the brand stage, small, while the big one is scrolled away. */
.peek {
  position: fixed; z-index: 58; bottom: calc(var(--tabbar) + 30px + var(--safe-bottom)); inset-inline-end: 16px;
  display: block; width: 72px; height: 138px; padding: 6px; border-radius: 22px; cursor: pointer;
  background: color-mix(in srgb, var(--bg-2) 85%, transparent); border: 1px solid var(--brand-line);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-lg), 0 0 36px -10px var(--brand-glow); animation: peek-in .45s var(--spring) both;
}
.peek.out { opacity: 0; transform: translateY(16px) scale(.9); transition: opacity .2s, transform .25s; }
@keyframes peek-in { from { opacity: 0; transform: translateY(16px) scale(.9); } }
.peek-phone { display: block; pointer-events: none; }
.peek .phone { box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / .14); }
.peek-eye { position: absolute; bottom: -8px; inset-inline-start: -8px; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--grad, var(--brand)); color: var(--on-brand); box-shadow: 0 6px 16px -6px var(--brand-glow), 0 0 0 3px var(--bg); }
.peek-eye .icon { width: 15px; height: 15px; }
@media (min-width: 1080px) {
  .peek { display: none; }
  .brand-nav { top: 0; margin-inline: 0; padding-top: 14px; }
  .brand-group { scroll-margin-top: 70px; }
}

/* Look choices: two cards, each with a sketch of the page it gives. */
.look-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.look-card { position: relative; display: flex; flex-direction: column; gap: 3px; padding: 10px 10px 14px; border-radius: 20px; background: var(--surface); border: 1.5px solid var(--line); cursor: pointer; transition: border-color .2s, box-shadow .25s, transform .3s var(--spring); }
.look-card input { position: absolute; opacity: 0; pointer-events: none; }
.look-card:has(input:checked) { border-color: var(--brand); box-shadow: 0 16px 36px -20px var(--brand-glow); }
.look-card:has(input:checked)::after { content: ''; position: absolute; top: 18px; inset-inline-end: 18px; width: 22px; height: 22px; border-radius: 50%; background: var(--brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 14px no-repeat; box-shadow: 0 0 0 3px var(--surface); animation: pop .4s var(--spring); }
.look-card:has(input:focus-visible) { outline: 2px solid var(--light); outline-offset: 2px; }
.look-card:active { transform: scale(.97); }
.look-card b { margin: 10px 4px 0; font-size: 15px; }
.look-card span { margin: 0 4px; font-size: 12px; line-height: 1.45; color: var(--text-2); }
.look-swatch { position: relative; height: 92px; border-radius: 14px; overflow: hidden; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .08); }
.look-swatch i { position: absolute; border-radius: 6px; }
.look-swatch i:nth-child(1) { inset-inline: 12px; top: 46%; height: 11px; background: rgb(255 255 255 / .15); }
.look-swatch i:nth-child(2) { inset-inline: 12px 34px; top: calc(46% + 17px); height: 11px; background: rgb(255 255 255 / .1); }
.look-swatch i:nth-child(3) { inset-inline: 22px; bottom: 9px; height: 12px; border-radius: 99px; }
.look-swatch.sw-night { background: radial-gradient(80% 70% at 20% 0%, color-mix(in srgb, var(--primary), #fff 22%), transparent 70%), radial-gradient(60% 60% at 100% 15%, color-mix(in srgb, var(--accent-lift) 60%, transparent), transparent 70%), var(--night); }
.look-swatch.sw-night i:nth-child(3) { background: var(--accent-lift); }
.look-swatch.sw-day { background: radial-gradient(70% 45% at 25% 0%, color-mix(in srgb, var(--primary), #fff 25%), transparent 70%), linear-gradient(var(--primary) 0 40%, var(--day) 40%); }
.look-swatch.sw-day i:nth-child(1), .look-swatch.sw-day i:nth-child(2) { background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / .1); }
.look-swatch.sw-day i:nth-child(3) { background: var(--accent-ink); }
/* The studio at night: ink, its violet and blue as light, the main action lit by its neon rim. */
.look-swatch.sw-studio { background: radial-gradient(70% 70% at 90% 0%, rgb(168 85 247 / .42), transparent 70%), radial-gradient(60% 60% at 0% 100%, rgb(59 130 246 / .32), transparent 70%), #0a0918; }
.look-swatch.sw-studio i:nth-child(1) { box-shadow: inset 0 1px 0 rgb(196 181 253 / .5); }
.look-swatch.sw-studio i:nth-child(3) { background: linear-gradient(135deg, #a855f7, #6366f1, #3b82f6); box-shadow: 0 0 0 1px rgb(196 181 253 / .55), 0 0 12px -1px rgb(168 85 247 / .75); }
.look-swatch.sw-salon { background: radial-gradient(70% 70% at 90% 0%, color-mix(in srgb, var(--accent-lift) 55%, transparent), transparent 70%), radial-gradient(60% 60% at 0% 100%, color-mix(in srgb, var(--primary-lift) 45%, transparent), transparent 70%), var(--night); }
.look-swatch.sw-salon i:nth-child(3) { background: var(--accent-lift); }

/* ==========================================================================
   Launch splash: the salon's icon and name, painted by the server, until the
   first screen is ready (a moment longer when opened from the home screen).
   ========================================================================== */
.splash { min-height: 100dvh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; padding: 24px; background: var(--bg); color: var(--text); text-align: center; }
.splash.overlay { position: fixed; inset: 0; z-index: 400; transition: opacity .5s ease, transform .6s var(--ease-out), filter .5s ease; }
.splash.out { opacity: 0; transform: scale(1.05); filter: blur(6px); pointer-events: none; }
.splash-mark { position: relative; width: 112px; height: 112px; margin-top: -6vh; margin-bottom: 16px; animation: pop .7s var(--spring) both; }
.splash-mark img { position: relative; width: 100%; height: 100%; border-radius: 30px; box-shadow: 0 24px 60px -18px rgb(0 0 0 / .7), 0 0 0 1px rgb(255 255 255 / .12), 0 0 60px -10px color-mix(in srgb, var(--bulb) 55%, transparent); }
/* The salon's page opens on its hero: the launch screen wears the same colours, and
   the same 18 round mirror bulbs as the hero light up around the icon (drawn in two
   alternating sets of nine, so they twinkle in turn while the ring slowly turns). */
.splash { --bulb: var(--brand); }
[data-theme='public'] .splash { --bulb: var(--hero-light); background: radial-gradient(60% 42% at 50% 42%, color-mix(in srgb, var(--hero-light) 14%, transparent), transparent 70%), var(--hero-bg); color: var(--hero-ink); }
.splash-mark::before, .splash-mark::after { content: ''; position: absolute; inset: -28px; border-radius: 50%; --bulb-glow: color-mix(in srgb, var(--bulb) 42%, transparent); animation: splash-bulbs 2.8s ease-in-out infinite, splash-turn 40s linear infinite; }
.splash-mark::before { background: radial-gradient(circle at 50% 3.57%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 79.84% 14.43%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 95.72% 41.94%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 90.21% 73.21%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 65.88% 93.63%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 34.12% 93.63%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 9.79% 73.22%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 4.28% 41.94%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 20.16% 14.43%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px); }
.splash-mark::after { background: radial-gradient(circle at 65.88% 6.37%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 90.21% 26.78%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 95.72% 58.06%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 79.84% 85.57%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 50% 96.43%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 20.16% 85.57%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 4.28% 58.06%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 9.79% 26.78%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px), radial-gradient(circle at 34.12% 6.37%, var(--bulb) 0 2.6px, var(--bulb-glow) 3.6px, transparent 8px); animation-delay: -1.4s, 0s; }
@keyframes splash-bulbs { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes splash-turn { to { rotate: 360deg; } }
.splash-name { font-size: 22px; font-weight: 700; animation: rise .7s var(--ease-out) .15s both; }
[data-theme='public'] .splash-name { font-size: 26px; line-height: 1.3; padding-block: .06em; background: var(--hero-title); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* ---------------------------------------------------------------- walk-ins and barbers' own studios */
.walk-in .walkin-now { display: inline-flex; align-items: center; gap: 8px; justify-self: start; height: 30px; margin-bottom: 4px; padding: 0 12px; border-radius: 99px; background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--text); font-size: 13px; font-weight: 500; }
.walk-in .walkin-now .live-dot { position: relative; inset: auto; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 22%, transparent); animation: live-dot 2s ease-in-out infinite; }
/* Its own soft pulse only: the salon cards' ping ring would spread over the whole sheet (and catch its taps). */
.walk-in .walkin-now .live-dot::after { display: none; }
/* Who serves him: the barbers free right now carry a green dot; asked for, the row lights up. */
.wi-free { flex: none; width: 8px; height: 8px; margin-inline-start: -2px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 22%, transparent); }
.wi-staff.need .chip-btn { border-color: var(--warn); }
.wi-hint { display: flex; align-items: center; gap: 6px; margin: 2px 2px 0; color: var(--warn); font-size: 13.5px; font-weight: 500; }
.wi-hint .icon { flex: none; width: 16px; height: 16px; }
/* Anything else, before the tap that records him: folded under one row, which sums it up. */
.walk-in .wi-more { margin-top: 18px; }
.wi-more .grow { min-width: 0; }
.wi-more .sub { color: var(--violet, var(--brand)); }
.wi-fold > .wi-extra { padding: 12px 4px 4px; margin: 0 -4px -4px; }
.wi-extra > .wi-done { margin-top: 12px; }
.wi-extra .field-label { margin-top: 18px; }
.walk-in .wi-tap { margin: -6px 2px 12px; }
/* What he wants: one tap on a service records him. The menu's order, never rearranged. */
.wi-services { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (min-width: 560px) { .wi-services { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.wi-svc { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-height: 84px; padding: 12px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); color: var(--text); font: inherit; text-align: start; cursor: pointer; transition: border-color .2s, background-color .2s, opacity .2s, transform .2s var(--spring); }
.wi-svc:hover { border-color: var(--brand-line); }
.wi-svc:active { transform: scale(.97); }
.wi-svc .svc-ic { flex: none; width: 22px; height: 22px; color: var(--violet, var(--brand)); }
.wi-svc .n { font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.wi-svc .p { margin-top: auto; font-size: 13px; color: var(--text-2); }
/* Not on the chosen barber's list: faded, still there (he may do it anyway). */
.wi-svc.off { opacity: .55; }
/* Recording: the tapped one spins, the others wait. */
.wi-svc:disabled { cursor: default; }
.wi-svc:disabled:not(.busy) { opacity: .4; }
.wi-svc.busy { border-color: var(--brand-line); background: var(--brand-soft); opacity: 1; }
.wi-svc.busy::after { content: ''; position: absolute; top: 12px; inset-inline-end: 12px; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--text); border-color: var(--text) transparent; animation: spin .7s linear infinite; }
.pill.src.walk { background: color-mix(in srgb, var(--ok) 14%, transparent); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
/* A barber's studio: one page, so no tab bar to leave room for, and no preview column. */
.studio.staff-mode .s-page { padding-bottom: calc(48px + var(--safe-bottom)); }
@media (min-width: 1080px) {
  .studio.staff-mode { grid-template-columns: 240px minmax(0, 1fr); }
}
/* His phone: a walk-in and a booking at the bottom, under his thumb, where the tab bar
   would be; the head's booking button steps aside. (After the padding above, which it raises.) */
.sched-dock {
  position: fixed; z-index: 55; bottom: calc(12px + var(--safe-bottom)); inset-inline: 12px; max-width: 520px; margin: 0 auto;
  display: flex; gap: 8px; padding: 8px; border-radius: 24px; background: color-mix(in srgb, var(--bg-2) 88%, transparent); border: 1px solid var(--line-2);
  backdrop-filter: blur(24px) saturate(1.8); -webkit-backdrop-filter: blur(24px) saturate(1.8); box-shadow: var(--shadow-lg);
}
.sched-dock .btn { height: 52px; gap: 8px; border-radius: 17px; font-size: 15.5px; }
.sched-dock .btn .icon { width: 20px; height: 20px; }
.sched-dock .walkin-btn { flex: 1; padding: 0 18px; }
.sched-dock .add-btn { flex: none; width: auto; padding: 0 18px; }
@media (max-width: 1079px) {
  .studio.staff-mode .sched-head .add-btn { display: none; }
  .studio.staff-mode .s-page { padding-bottom: calc(var(--tabbar) + 48px + var(--safe-bottom)); }
}
@media (min-width: 1080px) {
  .sched-dock { display: none; }
}
/* The owner gives a barber his sign-in: the number, and the password shown once. */
.login-box { display: grid; gap: 12px; }
.login-box .login-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); }
.login-box .login-row .tile { width: 40px; height: 40px; border-radius: 12px; }
.login-box .secret { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 16px; border-radius: 16px; border: 1px dashed var(--brand-line); background: var(--brand-soft); }
.login-box .secret b { font-size: 22px; letter-spacing: .06em; direction: ltr; font-variant-numeric: tabular-nums; }
.login-box .hint { font-size: 13px; line-height: 1.6; color: var(--text-2); }
.member .login-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--ok); }
.member .login-tag .icon { width: 12px; height: 12px; }

/* ---------------------------------------------------------------- the AI mirror
   Customers try a cut on their own photo: a card on the salon's page, then a sheet
   that walks from the selfie to a before/after they can book. */
.style-art { display: block; width: 100%; height: 100%; overflow: visible; }

/* On the salon's page: three drawn heads in a ring of light, and the way in. */
.p-tryon { position: relative; isolation: isolate; overflow: hidden; display: grid; justify-items: center; gap: 16px; padding: 22px 18px 18px; border-radius: 26px; text-align: center;
  background: radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--brand) 22%, transparent), transparent 62%), var(--surface);
  border: 1px solid var(--brand-line); box-shadow: var(--shadow), 0 26px 50px -30px color-mix(in srgb, var(--brand) 80%, transparent); }
/* A still light behind the card (no loop under the blur). */
.p-tryon-glow { position: absolute; inset: -40%; z-index: -1; background: conic-gradient(from 200deg, transparent 0 62%, color-mix(in srgb, var(--brand) 22%, transparent) 75%, transparent 88%); filter: blur(30px); pointer-events: none; }
.p-tryon-heads { display: flex; justify-content: center; align-items: flex-end; height: 104px; direction: ltr; }
.p-tryon-heads > span { position: relative; display: block; overflow: hidden; width: 78px; height: 78px; border-radius: 50%; color: var(--brand); background: radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--brand) 20%, transparent), transparent 70%), var(--surface-2); border: 1px solid var(--line-2); box-shadow: 0 14px 28px -16px rgb(0 0 0 / .6); }
.p-tryon-heads > span:nth-child(2) { z-index: 1; width: 98px; height: 98px; margin-inline: -14px; border-color: var(--brand-line); box-shadow: 0 0 0 4px var(--surface), 0 18px 36px -14px color-mix(in srgb, var(--brand) 70%, transparent); }
.p-tryon-heads > span:not(:nth-child(2)) { margin-bottom: 4px; opacity: .92; }
.p-tryon-heads > span { animation: float 5.5s ease-in-out infinite; animation-delay: calc(var(--i) * -1.8s); }
.p-tryon-text { display: grid; justify-items: center; gap: 6px; }
.p-tryon .eyebrow { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 11px; border-radius: 99px; background: var(--brand-soft); color: var(--text); font-weight: 600; }
.p-tryon .eyebrow .icon { width: 14px; height: 14px; color: var(--brand); }
.p-tryon h2 { max-width: 24ch; font-size: 21px; line-height: 1.35; text-wrap: balance; border-radius: 6px; }
.p-tryon h2:focus:not(:focus-visible) { outline: none; }
.p-tryon p { max-width: 44ch; font-size: 14px; line-height: 1.65; color: var(--text-2); }
.p-tryon-go { width: 100%; max-width: 340px; }
/* On a phone, under the menu, the card is a quarter smaller. */
@media (max-width: 559px) {
  .p-tryon { gap: 12px; padding: 16px 14px 14px; }
  .p-tryon-heads { height: 78px; }
  .p-tryon-heads > span { width: 58px; height: 58px; }
  .p-tryon-heads > span:nth-child(2) { width: 74px; height: 74px; margin-inline: -10px; }
  .p-tryon h2 { font-size: 18px; }
  .p-tryon p { font-size: 13.5px; line-height: 1.6; }
}
@media (min-width: 560px) {
  .p-tryon { grid-template-columns: auto minmax(0, 1fr); justify-items: start; column-gap: 22px; padding: 22px 24px; text-align: start; }
  .p-tryon-heads { grid-row: span 2; align-self: center; }
  .p-tryon-text { justify-items: start; }
  .p-tryon-go { width: auto; }
}
/* In the hero, the mirror's own button glows a little. */
/* Five of them on a narrow phone: a little smaller and closer. */
@media (max-width: 389px) {
  .p-actions:has(> .p-action:nth-child(5)) { gap: 8px; }
  .p-actions:has(> .p-action:nth-child(5)) .p-action { min-width: 52px; }
  .p-actions:has(> .p-action:nth-child(5)) .p-action .c { width: 48px; height: 48px; }
}
.p-action.ai .c { background: radial-gradient(circle at 30% 25%, color-mix(in srgb, var(--hero-light) 55%, transparent), color-mix(in srgb, var(--hero-light) 14%, transparent) 70%); border-color: color-mix(in srgb, var(--hero-light) 55%, transparent); box-shadow: 0 0 26px -6px color-mix(in srgb, var(--hero-light) 75%, transparent); }

/* The sheet. */
.mirror-sheet .sheet-body { overflow-x: hidden; }
.mr-step { display: grid; gap: 4px; animation: rise .5s var(--ease-out) both; }
.mr-h { display: flex; align-items: center; gap: 7px; margin: 18px 2px 10px; font-size: 15px; }
.mr-h .icon { width: 16px; height: 16px; color: var(--brand); }

/* 1. The photo: a vanity mirror's ring of bulbs, the tips, the consent. */
.mr-intro { justify-items: center; text-align: center; gap: 8px; }
.mr-orb { --ring: 66px; position: relative; display: grid; place-items: center; width: 150px; height: 150px; margin: 6px auto 4px; }
.mr-bulbs { position: absolute; inset: 0; }
.mr-bulbs i { position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 10px 2px color-mix(in srgb, var(--brand) 60%, transparent); transform: rotate(calc(var(--i) * 360deg / var(--n, 16))) translateY(calc(var(--ring) * -1)); animation: mirror-light 2.6s ease-in-out infinite; animation-delay: calc(var(--i) * -.16s); }
.mr-orb-core { display: grid; place-items: center; width: 96px; height: 96px; border-radius: 50%; color: var(--on-brand); background: var(--grad, var(--brand)); box-shadow: 0 0 0 6px var(--brand-soft), 0 20px 40px -14px color-mix(in srgb, var(--brand) 85%, transparent); animation: pop .7s var(--spring) both; }
.mr-orb-core .icon { width: 40px; height: 40px; }
.mr-intro h3 { font-size: 20px; }
.mr-intro > p { max-width: 38ch; font-size: 14px; line-height: 1.65; }
.mr-tips { display: grid; gap: 8px; width: 100%; margin: 12px 0 4px; padding: 0; list-style: none; text-align: start; }
.mr-tips li { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 16px; background: var(--surface-2); border: 1px solid var(--line); font-size: 14px; }
.mr-tips .ic { flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 11px; background: var(--brand-soft); color: var(--brand); }
.mr-tips .ic .icon { width: 17px; height: 17px; }
.mr-check { display: flex; align-items: flex-start; gap: 10px; width: 100%; margin-top: 8px; padding: 12px 14px; border-radius: 16px; border: 1px solid var(--line-2); font-size: 13px; line-height: 1.6; color: var(--text-2); text-align: start; cursor: pointer; }
.mr-check:has(input:checked) { border-color: var(--brand-line); background: var(--brand-soft); color: var(--text); }
.mr-check-input { flex: none; width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--brand); cursor: pointer; }
.mr-check a { color: var(--brand); text-decoration: underline; text-underline-offset: 3px; }
.mr-actions { display: grid; gap: 10px; width: 100%; margin-top: 14px; }

/* 1b. The camera: a mirror, an oval to stand in, a shutter. */
.mr-cam { position: relative; overflow: hidden; width: min(100%, 440px, calc(64dvh * .75)); aspect-ratio: 3 / 4; margin: 0 auto; border-radius: 26px; background: #000; }
.mr-video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
.mr-guide { position: absolute; inset: 0; pointer-events: none; }
.mr-guide i { position: absolute; left: 50%; top: 45%; width: 64%; aspect-ratio: 3 / 4; translate: -50% -50%; border-radius: 50%; border: 2px dashed rgb(255 255 255 / .75); box-shadow: 0 0 0 100vmax rgb(0 0 0 / .32); }
.mr-cam-hint { position: absolute; bottom: 14px; left: 50%; translate: -50% 0; max-width: calc(100% - 28px); padding: 7px 14px; border-radius: 99px; background: rgb(0 0 0 / .5); color: #fff; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.mr-cam.flash::after { content: ''; position: absolute; inset: 0; background: #fff; animation: mr-flash .45s ease-out both; }
@keyframes mr-flash { from { opacity: .95; } to { opacity: 0; } }
.mr-cam-bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; margin-top: 16px; }
.mr-cam-bar .link-btn { justify-self: start; }
.mr-shutter { display: grid; place-items: center; width: 76px; height: 76px; padding: 0; border-radius: 50%; border: 4px solid var(--text); background: transparent; cursor: pointer; transition: transform .2s var(--spring); }
.mr-shutter span { width: 58px; height: 58px; border-radius: 50%; background: var(--text); transition: transform .2s var(--spring); }
.mr-shutter:active span { transform: scale(.86); }

/* 2. The cut and the colour. */
.mr-me { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 18px; background: var(--surface-2); border: 1px solid var(--line); }
.mr-me img { flex: none; width: 54px; height: 54px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--brand-line); }
.mr-me .grow { display: grid; gap: 1px; font-size: 13px; }
.mr-me b { font-size: 15px; }
/* What the AI saw in his hair: small chips under his photo. */
.mr-traits { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.mr-traits span { display: inline-flex; align-items: center; height: 24px; padding: 0 9px; border-radius: 99px; background: var(--brand-soft); color: var(--text); font-size: 12px; font-weight: 500; }
/* A ribbon across the card's top edge, off the drawing (the hair tells the cuts apart). */
.mr-best { position: absolute; top: -9px; left: 50%; translate: -50% 0; z-index: 1; white-space: nowrap; box-shadow: 0 4px 10px -4px rgb(0 0 0 / .5); display: inline-flex; align-items: center; gap: 3px; height: 20px; padding: 0 7px; border-radius: 99px; background: var(--grad, var(--brand)); color: var(--on-brand); font-size: 10.5px; font-weight: 600; }
.mr-best .icon { width: 11px; height: 11px; }
.mr-hidden { display: flex; align-items: flex-start; gap: 8px; margin-top: 12px; font-size: 12.5px; line-height: 1.6; color: var(--text-3); }
.mr-hidden .icon { flex: none; width: 15px; height: 15px; margin-top: 2px; }
.mr-none { display: grid; justify-items: center; gap: 8px; margin-top: 16px; padding: 26px 18px; border-radius: 20px; border: 1px dashed var(--line-2); text-align: center; }
.mr-none .ic { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); }
.mr-none h3 { font-size: 17px; }
.mr-none p { max-width: 34ch; font-size: 13.5px; line-height: 1.6; }
.mr-styles { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 10px; }
.mr-styles:has(.mr-best) { row-gap: 16px; padding-top: 9px; }
.mr-style { position: relative; display: grid; justify-items: center; gap: 6px; padding: 5px 5px 9px; border-radius: 20px; border: 1px solid var(--line); background: radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--brand) 12%, transparent), transparent 70%), var(--surface); color: var(--text); font: inherit; cursor: pointer; transition: border-color .2s, box-shadow .25s, transform .3s var(--spring); animation: pop .45s var(--spring) both; animation-delay: calc(var(--i) * 30ms); }
/* The model's photo in each look, 3:4 like the photos; a drawn head until it is there. */
.mr-style .art { display: grid; place-items: center; width: 100%; aspect-ratio: 3 / 4; overflow: hidden; border-radius: 15px; background: var(--surface-2); color: var(--brand); }
.mr-style .art > * { transition: transform .5s var(--ease-out); }
.menu-photo { display: block; width: 100%; height: 100%; object-fit: cover; }
.mr-style .art > svg { width: 82%; height: auto; }
.mr-style.keep .art { box-shadow: inset 0 0 0 1px var(--line-2); }
.mr-menu + .mr-menu { margin-top: 6px; }
.mr-style .n { font-size: 12.5px; font-weight: 500; line-height: 1.35; text-align: center; }
.mr-style:active { transform: scale(.95); }
@media (hover: hover) { .mr-style:hover { border-color: var(--brand-line); } .mr-style:hover .art > * { transform: scale(1.05); } }
.mr-style.on { border-color: var(--brand); background: radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--brand) 26%, transparent), transparent 72%), var(--surface); box-shadow: 0 0 0 3px var(--brand-soft), 0 14px 28px -16px color-mix(in srgb, var(--brand) 80%, transparent); }
.mr-style.on::after { content: ''; position: absolute; top: 8px; inset-inline-end: 8px; width: 10px; height: 10px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px var(--surface), 0 0 10px var(--brand); }
.mr-shades { display: flex; flex-wrap: wrap; gap: 8px; }
.mr-shade { display: inline-flex; align-items: center; gap: 8px; height: 42px; padding-block: 0; padding-inline: 6px 14px; border-radius: 99px; border: 1px solid var(--line); background: var(--surface); color: var(--text-2); font: inherit; font-size: 13px; cursor: pointer; transition: border-color .2s, color .2s, box-shadow .25s; }
.mr-shade i { flex: none; width: 30px; height: 30px; border-radius: 50%; background: var(--sw, #2b1d16); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .18), inset 0 -6px 10px rgb(0 0 0 / .25); }
.mr-shade.natural i { background: conic-gradient(#15110f, #3b2418, #b9803f, #c8bba3, #a24a22, #15110f); }
.mr-shade.on { border-color: var(--brand); color: var(--text); box-shadow: 0 0 0 3px var(--brand-soft); }

/* 3. At work: the photo in a turning ring of light, a scan line, glints. */
.mr-working { justify-items: center; gap: 8px; text-align: center; padding-top: 6px; }
/* The light runs round the frame: a conic turning behind the photo as a layer (a transform,
   not a repainted gradient), square and wider than the frame's diagonal. */
.mr-frame { position: relative; isolation: isolate; overflow: hidden; width: min(78%, 300px); aspect-ratio: 3 / 4; padding: 3px; border-radius: 28px; background: var(--surface-2); box-shadow: 0 30px 60px -30px color-mix(in srgb, var(--brand) 90%, transparent); }
.mr-frame::before { content: ''; position: absolute; z-index: -1; left: 50%; top: 50%; width: 200%; aspect-ratio: 1; translate: -50% -50%; background: conic-gradient(var(--brand), transparent 22%, transparent 50%, var(--brand) 72%, transparent 92%); animation: ls-turn 2.6s linear infinite; }
.mr-frame img { width: 100%; height: 100%; border-radius: 25px; object-fit: cover; filter: saturate(.7) brightness(.9); animation: mr-breathe 3.2s ease-in-out infinite; }
@keyframes mr-breathe { 50% { transform: scale(1.03); filter: saturate(.9) brightness(1); } }
.mr-scan { position: absolute; inset: 3px; border-radius: 25px; overflow: hidden; pointer-events: none; }
.mr-scan::before { content: ''; position: absolute; inset-inline: 0; top: 0; height: 34%; background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--brand) 35%, transparent) 85%, color-mix(in srgb, var(--brand), #fff 50%)); mix-blend-mode: screen; animation: mr-scan 2.4s ease-in-out infinite alternate; }
@keyframes mr-scan { from { translate: 0 -100%; } to { translate: 0 300%; } }
.mr-glints { position: absolute; inset: 0; pointer-events: none; }
.mr-glints i { position: absolute; width: 14px; height: 14px; background: #fff; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%); filter: drop-shadow(0 0 6px var(--brand)); opacity: 0; animation: mr-glint 2.4s ease-in-out infinite; }
.mr-glints i:nth-child(1) { top: 18%; left: 22%; }
.mr-glints i:nth-child(2) { top: 30%; right: 18%; animation-delay: .8s; }
.mr-glints i:nth-child(3) { top: 12%; left: 56%; animation-delay: 1.6s; }
@keyframes mr-glint { 0%, 100% { opacity: 0; transform: scale(.4) rotate(0); } 40% { opacity: 1; transform: scale(1) rotate(45deg); } }
.mr-working h3 { margin-top: 14px; font-size: 19px; }
.mr-msg { min-height: 1.6em; color: var(--text-2); font-size: 14px; }
.mr-msg.in { animation: rise .45s var(--ease-out) both; }
/* A read that failed: the frame stops and the line says why, with Try again below. */
.mr-working.failed .mr-frame { filter: saturate(.4); }
.mr-working.failed .mr-frame::before { animation-play-state: paused; }
.mr-working.failed :is(.mr-scan, .mr-glints) { display: none; }
.mr-working.failed .mr-msg { color: var(--danger); }
.mr-chip { display: inline-flex; align-items: center; gap: 8px; height: 40px; margin-top: 6px; padding-block: 0; padding-inline: 4px 14px; border-radius: 99px; background: var(--surface-2); border: 1px solid var(--line); font-size: 13px; font-weight: 500; }
.mr-chip .art { width: 32px; height: 32px; overflow: hidden; border-radius: 50%; color: var(--brand); }

/* 4. The result: before and after with a slider between them, always left to right. */
.mr-compare { --x: 50%; position: relative; overflow: hidden; width: min(100%, 440px, calc(60dvh * .75)); aspect-ratio: 3 / 4; margin: 0 auto; border-radius: 26px; background: var(--surface-2); box-shadow: var(--shadow-lg), 0 0 0 1px var(--line-2); user-select: none; -webkit-user-select: none; }
.mr-compare img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.mr-after { position: absolute; inset: 0; clip-path: inset(0 0 0 var(--x)); }
.mr-handle { position: absolute; top: 0; bottom: 0; left: var(--x); width: 2px; margin-left: -1px; background: #fff; box-shadow: 0 0 12px rgb(0 0 0 / .45); pointer-events: none; }
.mr-handle span { position: absolute; top: 50%; left: 50%; display: grid; place-items: center; width: 42px; height: 42px; translate: -50% -50%; border-radius: 50%; background: #fff; color: #111; box-shadow: 0 6px 18px rgb(0 0 0 / .35); }
.mr-handle .icon { width: 20px; height: 20px; rotate: 90deg; }
.mr-tag { position: absolute; top: 12px; padding: 4px 11px; border-radius: 99px; background: rgb(0 0 0 / .48); color: #fff; font-size: 12px; font-weight: 600; pointer-events: none; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.mr-tag.is-before { left: 12px; }
.mr-tag.is-after { right: 12px; background: color-mix(in srgb, var(--brand) 82%, transparent); color: var(--on-brand); }
.mr-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; touch-action: pan-y; }
.mr-compare:has(.mr-range:focus-visible) { outline: 2px solid var(--light); outline-offset: 3px; }
.mr-result { gap: 12px; }
.mr-look { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 18px; background: linear-gradient(120deg, var(--brand-soft), transparent 70%), var(--surface); border: 1px solid var(--brand-line); }
.mr-look .art { flex: none; width: 48px; height: 48px; overflow: hidden; border-radius: 50%; background: var(--surface-2); color: var(--brand); }
.mr-look .grow { display: grid; gap: 1px; min-width: 0; font-size: 12.5px; }
.mr-look b { font-size: 15px; }
.mr-history .mr-h { margin-top: 6px; }
.mr-tried { gap: 10px; padding-bottom: 6px; }
.mr-thumb { flex: none; display: grid; gap: 5px; width: 78px; padding: 0; border: 0; background: none; color: var(--text-2); font: inherit; font-size: 11.5px; text-align: center; cursor: pointer; }
.mr-thumb img { width: 78px; height: 98px; border-radius: 16px; object-fit: cover; box-shadow: 0 0 0 1px var(--line-2); transition: box-shadow .25s, transform .3s var(--spring); }
.mr-thumb span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mr-thumb.on { color: var(--text); }
.mr-thumb.on img { box-shadow: 0 0 0 2px var(--brand), 0 0 0 5px var(--brand-soft); }
.mr-thumb:active img { transform: scale(.95); }
.mr-note { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; line-height: 1.6; color: var(--text-3); }
.mr-note .icon { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--brand); }

/* The look on the booking sheet and the booking's page. */
.tk-look-img { flex: none; width: 40px; height: 40px; border-radius: 13px; object-fit: cover; }
.tk-look .grow { display: grid; min-width: 0; }

/* The owner's side: the requested cut on the booking, and the setting. */
.look-box { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 12px 14px; border-radius: 16px; background: linear-gradient(120deg, var(--brand-soft), transparent 75%), var(--surface-2); border: 1px solid var(--brand-line); }
.look-box .art { flex: none; display: grid; place-items: center; width: 52px; height: 52px; overflow: hidden; border-radius: 50%; background: var(--surface-3); color: var(--violet, var(--brand)); }
.look-box .grow { display: grid; gap: 1px; min-width: 0; }
.look-box .eyebrow { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; }
.look-box .eyebrow .icon { width: 13px; height: 13px; color: var(--violet, var(--brand)); }
.look-box b { font-size: 15px; }
.look-sw { flex: none; width: 24px; height: 24px; border-radius: 50%; background: var(--sw); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .2), 0 0 0 3px var(--surface-3); }
.st-look { min-width: 0; color: var(--violet, var(--brand)); }
.st-look .icon { flex: none; width: 13px; height: 13px; }

/* ---------------------------------------------------------------- motion tiers
   motion.js sets html[data-motion]: full (everything), lite (a phone saving data, or with
   little memory and few cores: no glass blur on the floating bars, no ambient loops) or
   still (reduced motion: the rule at the end). Nothing moves while the tab is hidden. */
html.is-hidden *, html.is-hidden *::before, html.is-hidden *::after { animation-play-state: paused !important; }
:root[data-motion='lite'] :is(.s-tabbar, .savebar, .sheet-foot, .toast, .booking-top, .s-header.scrolled, .sched-dock, .p-bar) { -webkit-backdrop-filter: none; backdrop-filter: none; background: color-mix(in srgb, var(--bg-2) 96%, transparent); }
:root[data-motion='lite'] :is(.p-glass-btn, .p-status, .p-top-nav, .p-action .c, .p-cta-note, .sheet-backdrop) { -webkit-backdrop-filter: none; backdrop-filter: none; }
:root[data-motion='lite'] :is(.mini-lights, .mini-lights i, .p-lights i, .mr-bulbs i, .aurora i, .home-grid .mine .app-icon, .p-tryon-heads > span, .p-cue, .ls-ring, .ls-phone, .ls-spin, .ls-sat) { animation: none; }
:root[data-motion='lite'] .splash-mark::before, :root[data-motion='lite'] .splash-mark::after { animation: none; }

/* ---------------------------------------------------------------- motion preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
