@import url('/static/fonts.css');

/* ============================================================================
   Stemply — implementation of the Claude Design foundations.
   Dark by default. One accent (brass), one grid, one rule for where buttons live.
   Tokens below come from "Stemply Foundations"; do not drift from them.
   ========================================================================= */

:root{
  color-scheme:dark;

  /* — Colour & role ————————————————————————————— */
  --void:#0B0C0E;          /* page floor; never holds body text directly */
  --chrome:#111316;        /* rails, headers, sticky bars; glass blurs over this */
  --surface-hi:#1C1F24;    /* lit top of a card */
  --surface-lo:#15171B;    /* its shaded bottom */
  --well:#0E1013;          /* inset wells: code, table shells, fields */

  --ink:#F2F3F5;           /* 16.1:1 — headings, numbers, names */
  --ink-2:#A3A7AE;         /*  7.4:1 — body copy, table cells */
  --ink-3:#7B828A;         /*  4.6:1 — small caps labels only. Contrast floor. */
  --ink-4:#5A5F67;         /* decoration and disabled glyphs, never text */

  --brass:#C9A96A;         /* 9.2:1 — the single next action, live progress */
  --brass-hi:#E0C48C;
  --brass-dim:#A88949;
  --brass-deep:#8A6E35;
  --brass-wash:#20180A;
  --on-brass:#1A1405;

  --danger:#E4736B;
  --danger-deep:#C0524B;
  --danger-wash:#1A0D0C;
  --good:#7FBF9A;

  --hair:rgba(255,255,255,.07);
  --hair-soft:rgba(255,255,255,.05);
  --hair-hard:rgba(255,255,255,.14);

  /* — Space (base 4) ————————————————————————————— */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:40px; --s7:64px; --s8:96px;
  --pad-card:22px;
  --gutter:40px;

  /* — Radius ——————————————————————————————————— */
  --r-cell:4px;
  --r-control:8px;        /* inputs and buttons */
  --r-card:14px;
  --r-sheet:22px;         /* sheets, modals, phone screens */

  /* — Elevation: studio lighting ———————————————————— */
  --e1:inset 0 1px 0 rgba(255,255,255,.06);
  --e2:inset 0 1px 0 rgba(255,255,255,.06),0 18px 40px -26px rgba(0,0,0,.9);
  --e3:inset 0 1px 0 rgba(255,255,255,.08),0 40px 80px -32px rgba(0,0,0,.9);

  /* — Motion ——————————————————————————————————— */
  --t-state:120ms ease-out;
  --t-enter:220ms cubic-bezier(.2,.8,.2,1);
  --t-surface:280ms cubic-bezier(.2,.8,.2,1);

  font-family:Manrope,-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  font-synthesis:none;
  -webkit-font-smoothing:antialiased;
  color:var(--ink);
  background:var(--void);

  /* Desktop is drawn one step larger, the way a browser at 125% would. Phones
     and tablets stay at 1:1 -- a phone screen has no spare room to give away,
     and its text is already sized for arm's length.

     Zoom on the root also narrows the layout viewport, so max-widths and grids
     keep working against the room that is really left; that is why this beats
     scaling every token by hand, half of which are hardcoded px anyway.

     What zoom does NOT scale is vw/vh: they stay measured against the unzoomed
     viewport, so a bare 100vh would paint a quarter taller than the screen and
     hand the page a permanent scrollbar. Use --vw / --vh below, never raw
     viewport units. */
  --zoom:1;
  --vw:1vw;
  --vh:1vh;
  --svh:1svh;
  zoom:var(--zoom);

  --scroll-thumb:rgba(201,169,106,.30);
  --scroll-thumb-hi:rgba(201,169,106,.55);

  /* Everything on the sign-in screen except the card, measured on a phone:
     64 topbar + 363 panel + 17 gap + 34 padding, rounded up for slack. The
     card takes whatever height is left after this. */
  --auth-chrome:490px;
}
/* Media queries are evaluated against the real viewport, never the zoomed
   layout box, so this threshold means real pixels -- and it is the same
   1081px that separates the app's desktop layout from the stacked one.
   A mouse only: an iPad on its side is 1180px wide too, and a touch screen
   held at arm's length is the case the 1:1 above is for. */
@media(min-width:1081px) and (hover:hover) and (pointer:fine){
  :root{
    --zoom:1.25;
    --vw:calc(1vw / 1.25);
    --vh:calc(1vh / 1.25);
    --svh:calc(1svh / 1.25);
  }
}

*{box-sizing:border-box}
/* touch-action does not inherit, so declaring it on body alone leaves every
   computed value below at `auto`. Say it again on everything tappable. */
a,button,.button,input,textarea,select,label,summary,.keypad-grid button{touch-action:manipulation}

body{
  margin:0;
  /* Kills the double-tap-to-zoom gesture, which on iOS fires whenever two taps
     land close together -- tapping a field, then its label, or two PIN keys in
     a row, would jump the page. Pinch zoom is untouched: this only removes the
     gesture, so nothing about accessibility is given up. It also drops the
     300ms wait Safari spends deciding whether a tap was the first of two. */
  touch-action:manipulation;
  font-size:15px;
  line-height:1.6;
  color:var(--ink);
  /* Deliberately transparent, with the page colour left on :root. Because the
     root carries its own background, a background here would paint in the
     block-background step -- after negative z-index descendants -- and bury
     the decorative light layer below. That is exactly what hid it. */
  background:transparent;
  min-height:calc(100 * var(--vh));
}

/* Two decorative light sources, fixed and non-interactive: the parallax
   layers never sit under anything clickable. */
body::before{
  content:'';
  position:fixed;
  inset:0;
  z-index:-1;
  pointer-events:none;
  background:
    radial-gradient(110% 70% at 16% -8%,rgba(201,169,106,.10),transparent 62%),
    radial-gradient(90% 60% at 92% 2%,rgba(128,148,208,.07),transparent 60%);
}

/* ---------- Type ---------------------------------------------------------- */
h1,h2,h3,p{margin-top:0}
h1{font-size:40px;line-height:1.08;font-weight:300;letter-spacing:-.028em;margin-bottom:0}
h2{font-size:28px;line-height:1.15;font-weight:400;letter-spacing:-.022em;margin-bottom:var(--s4)}
h3{font-size:17px;line-height:1.35;font-weight:600;letter-spacing:-.012em;margin-bottom:var(--s3)}
p{color:var(--ink-2);text-wrap:pretty}
small{font-size:13px;line-height:1.5;color:var(--ink-3)}
strong{font-weight:600}
a{color:var(--brass);text-decoration:none;transition:color var(--t-state)}
a:hover{color:var(--brass-hi)}
code,.mono,.num{font-family:'JetBrains Mono',ui-monospace,monospace;font-feature-settings:'tnum'}
.display{font-size:56px;line-height:1.02;font-weight:300;letter-spacing:-.032em;text-wrap:balance}

/* Small caps labels: the only place --ink-3 is allowed to carry text. */
.eyebrow{display:block;font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.muted{color:var(--ink-2)}
.count{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);font-weight:600}

/* ---------- The button rule ---------------------------------------------- */
/* 1 · exactly one brass button per view, and it commits.
   2 · it lives at the end of the form it submits.
   3 · header buttons are outline and only open something.
   4 · destructive stays in its own row as an icon, behind a confirm.
   5 · links navigate only.
   6 · 44px minimum everywhere; cashier actions 64px. */

button,input,textarea,select{font-family:inherit;font-size:inherit}

button,.button{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:44px;padding:0 18px;
  border:1px solid var(--hair-hard);
  border-radius:var(--r-control);
  background:rgba(255,255,255,.03);
  color:var(--ink);
  font-size:14px;font-weight:600;letter-spacing:-.006em;
  white-space:nowrap;        /* labels never truncate — German sets the width */
  cursor:pointer;
  box-shadow:var(--e1);
  transition:background var(--t-state),border-color var(--t-state),color var(--t-state),opacity var(--t-state);
}
button:hover,.button:hover{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.2)}
button:disabled,.button:disabled{opacity:.4;cursor:not-allowed}

button.primary,.button.primary{
  background:linear-gradient(180deg,var(--brass-hi),var(--brass));
  border-color:var(--brass-deep);
  color:var(--on-brass);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 10px 26px -12px rgba(201,169,106,.65);
}
button.primary:hover,.button.primary:hover{background:linear-gradient(180deg,#EED5A6,var(--brass-hi));border-color:var(--brass-dim)}

button.ghost,.button.ghost{background:transparent;border-color:transparent;color:var(--ink-2);font-weight:500}
button.ghost:hover,.button.ghost:hover{background:rgba(255,255,255,.05);color:var(--ink);border-color:transparent}

button.destructive,.button.destructive{
  background:linear-gradient(180deg,var(--danger),var(--danger-deep));
  border-color:var(--danger-deep);color:#1A0D0C;
}

button.sm,.button.sm{min-height:36px;padding:0 12px;font-size:13px;gap:8px}

/* Destructive in-row: an icon, never a labelled button beside the primary. */
.icon-button{
  width:44px;min-width:44px;height:44px;padding:0;
  border-color:transparent;background:transparent;color:var(--ink-3);box-shadow:none;
}
.icon-button:hover{background:rgba(255,255,255,.06);color:var(--ink)}
.icon-button.danger:hover{background:var(--danger-wash);color:var(--danger);border-color:rgba(228,115,107,.3)}

.icon{width:20px;height:20px;flex-shrink:0}
button.sm .icon,.button.sm .icon{width:16px;height:16px}

/* Form actions sit at the end: secondary left, brass right. */
.form-actions{display:flex;justify-content:flex-end;align-items:center;gap:var(--s3);margin-top:var(--s5)}

:focus-visible{outline:2px solid var(--brass);outline-offset:2px;border-radius:var(--r-control)}

/* ---------- Fields -------------------------------------------------------- */
label{display:block;font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin:0 0 var(--s2)}
.field{margin-bottom:var(--s4)}

input,select,textarea{
  width:100%;min-height:44px;padding:11px 14px;
  border:1px solid var(--hair-hard);border-radius:var(--r-control);
  background:var(--well);color:var(--ink);font-size:15px;
  transition:border-color var(--t-state),box-shadow var(--t-state),background var(--t-state);
}
input::placeholder,textarea::placeholder{color:var(--ink-4)}
input:hover,select:hover,textarea:hover{border-color:rgba(255,255,255,.2)}
input:focus,select:focus,textarea:focus{
  outline:none;border-color:var(--brass-dim);
  box-shadow:0 0 0 3px rgba(201,169,106,.16);background:#101215;
}
textarea{resize:vertical;min-height:120px;line-height:1.6}
input[type=checkbox]{width:18px;min-width:18px;min-height:18px;accent-color:var(--brass)}
.checkbox{display:flex;align-items:center;gap:var(--s3);text-transform:none;letter-spacing:0;font-size:14px;font-weight:500;color:var(--ink-2)}
.checkbox input{margin:0}

.form-error{
  margin:0 0 var(--s4);padding:12px 14px;
  border:1px solid rgba(228,115,107,.3);border-left:2px solid var(--danger);
  border-radius:var(--r-control);background:var(--danger-wash);
  color:#F0ABA2;font-size:14px;
}

/* ---------- Shell: rail + work surface ------------------------------------ */
.shell{display:grid;grid-template-columns:248px minmax(0,1fr);min-height:calc(100 * var(--vh))}

.rail{
  /* The height of the screen, not of its contents: on a 768px laptop the eight
     links plus the business and the actions come to 864px, and with a minimum
     the rail simply grew and took sign-out below the fold. Now the list inside
     gives way instead, and the actions never move. */
  position:sticky;top:0;align-self:start;height:calc(100 * var(--vh));
  /* One scroller, and only when a window is short enough to need it. Putting
     it on the list instead scrolled four links at a time, because the other
     four are siblings of the list, not children of it. */
  overflow-y:auto;overflow-x:hidden;scrollbar-width:none;
  display:flex;flex-direction:column;gap:var(--s5);
  padding:var(--s5) var(--s4);
  background:rgba(17,19,22,.72);
  backdrop-filter:blur(20px) saturate(1.2);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  border-right:1px solid var(--hair);
}

.brand{display:flex;align-items:center;gap:var(--s3);padding:var(--s2) var(--s3)}
.brand-mark{color:var(--brass);flex-shrink:0}
.brand-word{font-size:13px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink)}
.brand-row{display:flex;align-items:center;justify-content:space-between;gap:var(--s2)}
.plan-badge{flex:none;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:700;letter-spacing:.04em;white-space:nowrap;
  color:var(--on-brass);background:linear-gradient(180deg,var(--brass),var(--brass-deep));text-decoration:none}
.plan-badge.is-demo{color:var(--brass);background:transparent;box-shadow:inset 0 0 0 1px var(--brass)}
.plan-badge:hover{filter:brightness(1.08)}

/* On a wide screen the sheet is not a sheet: display:contents dissolves the
   wrapper so its nav and foot lay out as ordinary children of the rail, which
   is the two-tier column this has always been. */
.rail-rest{display:contents}
.rail-more{display:none}
/* The two groups read as one list: the rail's gap between them is taken back
   down to the 2px step between links (the gap changes with height below). */
@media(min-width:1351px){.rail-nav-rest{margin-top:calc(2px - var(--s5))}}
.rail::-webkit-scrollbar{display:none}
.rail-nav{display:flex;flex-direction:column;gap:2px;flex:0 0 auto;scrollbar-width:none}
.rail-nav::-webkit-scrollbar{display:none}
.rail-link{
  display:flex;align-items:center;gap:var(--s3);
  min-height:44px;padding:0 var(--s3);border-radius:var(--r-control);
  color:var(--ink-3);font-size:14px;font-weight:500;
  transition:color var(--t-state),background var(--t-state);
}
.rail-link .icon{color:var(--ink-4);transition:color var(--t-state)}
.rail-link:hover{color:var(--ink-2);background:rgba(255,255,255,.03)}
.rail-link:hover .icon{color:var(--ink-3)}
.rail-link.selected{color:var(--ink);background:rgba(255,255,255,.05);box-shadow:var(--e1)}
.rail-link.selected .icon{color:var(--brass)}

/* The business, the theme, the language and the way out. They ride at the
   bottom of the rail whatever happens above them, so nothing has to be
   scrolled to sign out. The background is the rail's own, rendered flat,
   because a translucent panel over scrolling links reads as a smear. */
.rail-foot{
  display:flex;flex-direction:column;gap:var(--s3);margin-top:auto;
  position:sticky;bottom:calc(var(--s5) * -1);
  padding-top:var(--s4);padding-bottom:var(--s5);border-top:1px solid var(--hair);
  background:#101215;
}
[data-theme=light] .rail-foot{background:#FDFDFE}
.rail-tenant{display:flex;align-items:center;gap:var(--s3);padding:0 var(--s1);min-width:0}
.rail-tenant-mark{
  flex-shrink:0;width:30px;height:30px;display:grid;place-items:center;
  border-radius:var(--r-control);background:var(--brass-wash);
  border:1px solid rgba(201,169,106,.28);color:var(--brass);font-size:12px;font-weight:700;
}
.rail-tenant-name{display:block;font-size:14px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail-tenant-place{display:block;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.rail-actions{display:flex;align-items:center;gap:var(--s2)}
.rail-actions .logout-form{flex:1}
.rail-actions .logout-form>button{width:100%;justify-content:flex-start}

/* A short laptop is the common one: 1366x768 is still the most widespread
   screen there is. Tightening the rail there keeps everything in view without
   scrolling anything at all. */
@media(min-width:1351px) and (max-height:1000px){
  .rail{gap:var(--s3);padding:var(--s4)}
  .rail .brand{padding:var(--s1) var(--s3)}
  .rail-link{min-height:38px;font-size:13.5px}
  .rail-foot{padding-top:var(--s3);padding-bottom:var(--s4);gap:var(--s2)}
  .rail-foot{bottom:calc(var(--s4) * -1)}
  .rail-nav-rest{margin-top:calc(2px - var(--s3))}
}
@media(min-width:1351px) and (max-height:780px){
  .rail{gap:var(--s2)}
  .rail-nav-rest{margin-top:calc(2px - var(--s2))}
  .rail-link{min-height:34px}
  .rail-tenant small,.rail-tenant-place{display:none}
}
@media(min-width:1351px) and (max-height:660px){
  .rail-link{min-height:30px;font-size:13px}
}

.work{display:flex;flex-direction:column;min-width:0;position:relative}
/* While a section is being dragged sideways the outgoing and incoming panels
   both stick out of the frame; clipping only for the duration keeps sticky and
   pop-out things working the rest of the time. */
.work.swiping{overflow-x:clip}
.panel-ghost{
  position:absolute;left:0;right:0;overflow:hidden;pointer-events:none;
  will-change:transform;
}
.container{width:100%;max-width:1240px;margin:0 auto;padding:var(--s7) var(--gutter) var(--s8);flex:1}

/* ---------- Page header: outline actions only ----------------------------- */
.page-heading{
  display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s5);
  margin-bottom:var(--s6);padding-bottom:var(--s5);
  border-bottom:1px solid var(--hair);
}
.page-heading .eyebrow{margin-bottom:var(--s3)}
.page-heading p{margin:var(--s2) 0 0;font-size:14px}
.head-actions{display:flex;align-items:center;gap:var(--s3);flex-shrink:0}

/* ---------- Surfaces ------------------------------------------------------ */
.panel{
  padding:var(--pad-card);margin-bottom:var(--s5);
  border:1px solid var(--hair);border-radius:var(--r-card);
  background:linear-gradient(180deg,var(--surface-hi),var(--surface-lo));
  box-shadow:var(--e2);
}
.panel-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:var(--s4);
  margin:0 0 var(--s4);padding-bottom:var(--s3);border-bottom:1px solid var(--hair);
}
.panel-head h2,.panel-head h3{margin:0;font-size:17px;font-weight:600;letter-spacing:-.012em}
.narrow{max-width:520px}
.split{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5);align-items:start}
.split-wide{grid-template-columns:1.4fr 1fr}
.grow{flex:1;min-width:0}

.notice{
  display:flex;align-items:center;gap:var(--s3);
  padding:14px 18px;margin-bottom:var(--s5);
  border:1px solid var(--hair-hard);border-left:2px solid var(--brass);
  border-radius:var(--r-control);background:rgba(201,169,106,.06);
  font-size:14px;color:var(--ink-2);
}
.notice .icon{color:var(--brass)}
.notice.warning{border-left-color:var(--danger);background:rgba(228,115,107,.06)}
.notice.warning .icon{color:var(--danger)}
.notice a{font-weight:600;white-space:nowrap}

/* ---------- Metrics ------------------------------------------------------- */
.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4);margin-bottom:var(--s5)}
.metric{
  padding:var(--pad-card);
  border:1px solid var(--hair);border-radius:var(--r-card);
  background:linear-gradient(180deg,var(--surface-hi),var(--surface-lo));
  box-shadow:var(--e2);
}
.metric-label{display:block;font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.metric-value{
  display:block;margin:var(--s4) 0 var(--s1);
  font-size:40px;line-height:1;font-weight:300;letter-spacing:-.028em;
  font-family:'JetBrains Mono',ui-monospace,monospace;font-feature-settings:'tnum';
}
.metric-date{font-size:clamp(20px,calc(5.2 * var(--vw)),28px)}
.metric-note{font-size:13px;color:var(--ink-3)}
.metric-note.up{color:var(--good)}

/* The lead metric is the one the owner came for: it gets the light. */
.metric.lead{
  border-color:rgba(201,169,106,.26);
  background:
    radial-gradient(120% 100% at 0% 0%,rgba(201,169,106,.13),transparent 60%),
    linear-gradient(180deg,var(--surface-hi),var(--surface-lo));
}
.metric.lead .metric-value{color:var(--brass)}

/* ---------- Ratio bars ---------------------------------------------------- */
.ratios{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
.ratio-label{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s3)}
.ratio-label span:first-child{font-size:13px;color:var(--ink-2)}
.ratio-value{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:20px;font-weight:500;color:var(--ink)}
.ratio-track{height:4px;border-radius:999px;background:rgba(255,255,255,.07);overflow:hidden}
.ratio-fill{
  display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,var(--brass-deep),var(--brass));
  transform-origin:left;animation:ratio-in var(--t-surface) both;
}
@keyframes ratio-in{from{transform:scaleX(0)}}
.ratio-note{display:block;margin-top:var(--s2);font-size:12px;color:var(--ink-3)}

/* ---------- Chart --------------------------------------------------------- */
.chart{display:flex;align-items:flex-end;gap:clamp(4px,calc(1.4 * var(--vw)),16px);min-height:200px;padding-top:var(--s5);overflow-x:auto;scrollbar-width:thin}
.chart-column{flex:1;min-width:26px;max-width:76px;display:flex;flex-direction:column;align-items:center}
.chart-count{font-size:12px;color:var(--ink-3);font-family:'JetBrains Mono',ui-monospace,monospace}
.chart-bar{
  width:100%;max-width:40px;margin-top:var(--s2);min-height:3px;
  border-radius:var(--r-cell) var(--r-cell) 2px 2px;
  background:linear-gradient(180deg,rgba(201,169,106,.34),rgba(201,169,106,.06));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14);
  animation:bar-rise var(--t-surface) both;
}
.chart-column:last-child .chart-bar{
  background:linear-gradient(180deg,var(--brass),rgba(201,169,106,.2));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 0 24px -8px rgba(201,169,106,.7);
}
@keyframes bar-rise{from{transform:scaleY(0);transform-origin:bottom;opacity:0}}
.chart-day{margin-top:var(--s3);font-size:11px;color:var(--ink-4);white-space:nowrap;font-family:'JetBrains Mono',ui-monospace,monospace}

/* ---------- Tables and lists ---------------------------------------------- */
.table-wrap{overflow-x:auto;border:1px solid var(--hair);border-radius:var(--r-card);background:var(--well)}
table{border-collapse:collapse;width:100%;font-size:14px}
th{
  text-align:left;padding:12px var(--s4);
  font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);
  border-bottom:1px solid var(--hair);background:rgba(255,255,255,.012);
}
td{padding:14px var(--s4);border-bottom:1px solid var(--hair-soft);color:var(--ink-2)}
tbody tr:last-child td{border-bottom:0}
tbody tr{transition:background var(--t-state)}
tbody tr:hover{background:rgba(255,255,255,.02)}
td strong{color:var(--ink);font-weight:600}
td .code{display:block;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12px;color:var(--ink-4);margin-top:2px}
.num{text-align:right;font-family:'JetBrains Mono',ui-monospace,monospace;color:var(--ink)}
.row-actions{width:1%;white-space:nowrap;text-align:right;padding-right:var(--s3)}

.entity-list{list-style:none;padding:0;margin:0}
.entity-list li{display:flex;align-items:center;gap:var(--s4);padding:var(--s4) 0;border-bottom:1px solid var(--hair-soft)}
.entity-list li:last-child{border-bottom:0}
.entity-list li>.grow>strong{display:block;color:var(--ink)}
.entity-list li>.grow>small{display:block;margin-top:2px;font-size:12px;color:var(--ink-3)}
.activity-list{list-style:none;padding:0;margin:0}
.activity-list li{padding:var(--s4) 0;border-bottom:1px solid var(--hair-soft)}
.activity-list li:last-child{border-bottom:0}
.activity-list p{margin:0 0 var(--s1);color:var(--ink);white-space:pre-wrap}

.avatar{
  flex-shrink:0;width:40px;height:40px;display:grid;place-items:center;border-radius:999px;
  background:var(--brass-wash);border:1px solid rgba(201,169,106,.26);
  color:var(--brass);font-weight:600;font-size:15px;
}
.chip{
  display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;
  border:1px solid var(--hair-hard);background:rgba(255,255,255,.03);
  font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);
}
/* The PIN sits in the cashier row so the owner can read it out over the
   counter. Tabular figures: four digits should not shuffle between rows. */
.pin-chip{display:inline-flex;align-items:baseline;gap:7px}
.pin-chip small{font-size:9px;letter-spacing:.14em;color:var(--ink-3)}
.pin-chip b{
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-feature-settings:'tnum';font-size:14px;font-weight:500;letter-spacing:.08em;color:var(--brass);
}
.pin-chip.muted b{color:var(--ink-4);letter-spacing:.02em}
.chip.ok{border-color:rgba(127,191,154,.3);background:rgba(127,191,154,.08);color:var(--good)}
.chip.warn{border-color:rgba(228,115,107,.3);background:var(--danger-wash);color:var(--danger)}

.pagination{display:flex;gap:var(--s4);justify-content:flex-end;align-items:center;margin-top:var(--s4)}

/* ---------- Empty states -------------------------------------------------- */
.empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--s3);padding:var(--s7) var(--s5)}
.empty-state .icon{width:28px;height:28px;color:var(--ink-4)}
.empty-state h3{margin:0;color:var(--ink)}
.empty-state p{margin:0;max-width:44ch;font-size:14px}
.empty-state button,.empty-state .button{margin-top:var(--s2)}

/* ---------- Disclosure ---------------------------------------------------- */
.disclosure{padding:0;overflow:hidden}
.disclosure>summary{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  min-height:64px;padding:0 var(--pad-card);
  cursor:pointer;list-style:none;transition:background var(--t-state);
}
.disclosure>summary::-webkit-details-marker{display:none}
.disclosure>summary:hover{background:rgba(255,255,255,.025)}
.disclosure-title{display:flex;align-items:center;gap:var(--s3);font-size:15px;font-weight:600;color:var(--ink)}
.disclosure-title .icon{color:var(--brass)}
.disclosure-body{padding:var(--s5) var(--pad-card) var(--pad-card);border-top:1px solid var(--hair)}
.chev{
  width:8px;height:8px;flex-shrink:0;
  border-right:1.6px solid var(--ink-3);border-bottom:1.6px solid var(--ink-3);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform var(--t-surface);
}
.disclosure[open]>summary .chev,.language-picker[open] .chev{transform:rotate(-135deg) translate(-2px,-2px)}

/* ---------- "no account yet" on the sign-in panel -------------------------
   The scene is built to fit any screen without scrolling and has around forty
   pixels of slack, so the page carries one line and the answer opens over it. */
/* The link is lifted out of the flow: at 360x640 in German the scene has
   three pixels left, and a taller line here spends all of them. */
.panel-top{position:relative}
.panel-top .linkish{position:absolute;right:0;top:0;font-size:12.5px;line-height:1.35}
.linkish{
  background:none;border:0;padding:0;min-height:0;box-shadow:none;
  color:var(--ink-3);font:inherit;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px;text-decoration-thickness:1px;
  transition:color var(--t-state);
}
.linkish:hover{color:var(--brass)}
.ask-dialog{max-width:440px;text-align:left}
.ask-dialog .eyebrow{display:block;margin-bottom:9px;padding-right:40px}
.ask-dialog p{margin:0;color:var(--ink-2);font-size:14.5px;line-height:1.55}
.ask-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:15px}
.ask-pill{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:0;padding:10px 6px;border-radius:999px;border:1px solid var(--hair-hard);
  background:rgba(255,255,255,.03);color:var(--ink-2);font-size:13px;white-space:nowrap;
  text-decoration:none;cursor:pointer;box-shadow:none;
  transition:border-color var(--t-state),color var(--t-state),background var(--t-state);
}
.ask-pill .icon{width:15px;height:15px;flex:0 0 auto}
.ask-pill:hover{border-color:var(--brass);color:var(--brass);background:var(--brass-wash)}
.ask-pill.copied{border-color:var(--good);color:var(--good)}
@media(max-width:360px){.ask-pill{font-size:12.5px;gap:6px}.ask-pill .icon{width:14px;height:14px}}

/* A field and its button on one line, for a table cell that edits. */
.inline-form{display:flex;gap:var(--s2);align-items:center}
.inline-form input{min-width:0;flex:1 1 auto}

/* ---------- status list and meter (super-admin monitor) ------------------
   A service is either answering or it is not, so the row says so with one dot
   and one line of evidence rather than a chart nobody reads. */
.status-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.status-list li{
  display:flex;align-items:center;gap:var(--s3);
  padding:var(--s3) 0;border-bottom:1px solid var(--hair-soft);
}
.status-list li:last-child{border-bottom:0}
.status-list strong{font-size:15px;font-weight:600}
.status-list small{color:var(--ink-3);font-size:13px;font-family:'JetBrains Mono',ui-monospace,monospace}
.status-dot{
  width:9px;height:9px;border-radius:999px;flex:0 0 auto;
  background:var(--good);box-shadow:0 0 0 4px rgba(40,114,73,.16);
}
.status-list li.down .status-dot{background:var(--danger);box-shadow:0 0 0 4px rgba(167,53,48,.18)}
.meter{height:10px;border-radius:999px;background:var(--well);overflow:hidden;border:1px solid var(--hair)}
.meter span{
  display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,var(--brass-deep),var(--brass));
}

/* ---------- Wallet previews ------------------------------------------------
   The same pass twice, each in its platform's own chrome, at the proportions
   the phones actually use: Apple fills the card with the business colour, hangs
   a header field beside the logo, runs the strip picture edge to edge and puts
   the barcode on its own white plate; Google paints a band at the top and
   leaves everything under it white. That is why the same three colours look so
   different on the two phones, and why an owner needs to see both. */
.card-stage{
  display:flex;flex-direction:column;align-items:center;gap:var(--s4);
  padding:var(--s6) var(--s5);
  border:1px solid var(--hair);border-radius:var(--r-card);
  background:radial-gradient(90% 60% at 50% 0%,rgba(255,255,255,.04),transparent 62%),var(--well);
}
.pass{width:100%;max-width:320px;overflow:hidden;user-select:none}

/* Apple: storeCard. */
.pass-apple{
  --gutter:15px;
  /* The phone gives a store card a fixed shape and puts the code at the foot
     of it, whatever is above; the space in between is part of the look. */
  aspect-ratio:458/640;display:flex;flex-direction:column;
  border-radius:16px;padding:14px var(--gutter) 16px;
  background:var(--card-bg);color:var(--card-fg);
  box-shadow:0 34px 66px -30px rgba(0,0,0,.85),inset 0 1px 0 rgba(255,255,255,.16);
}
.a-head{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:40px}
.a-logo{height:32px;width:auto;max-width:58%;object-fit:contain;object-position:left center}
.a-name{font-size:15px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-field{display:flex;flex-direction:column;gap:2px;min-width:0}
.a-field small{
  font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--card-label);white-space:nowrap;
}
.a-field b{font-size:21px;font-weight:400;letter-spacing:-.01em;line-height:1.15;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.a-right{align-items:flex-end;text-align:right;flex-shrink:0}
.a-middle{align-items:center;text-align:center}
/* Full width, and cropped the way iOS crops it: the artwork is 375x290,
   the phone shows the middle 375x148 of it. */
.a-strip{display:block;width:calc(100% + var(--gutter) * 2);margin:13px calc(var(--gutter) * -1) 0;
  aspect-ratio:375/148;object-fit:cover}
.a-fields{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:13px 1px 0}
.a-fields .a-field{flex:1 1 0;min-width:0;overflow:hidden}
.a-fields .a-field b{display:block;max-width:100%}
.a-head-field b{font-size:15px}
.pass-apple .a-fields .a-field b{font-size:19px}
.pass-apple .a-code img{width:112px;height:112px}
.a-code{
  width:max-content;margin:auto auto 4%;padding:11px;border-radius:8px;background:#fff;
  display:flex;flex-direction:column;align-items:center;
}

/* Google: generic pass, the whole card in the business colour. */
.pass-google{
  border-radius:20px;background:var(--card-bg);color:#fff;
  box-shadow:0 34px 66px -30px rgba(0,0,0,.85);
}
.pass-google .g-band{border-bottom:1px solid rgba(255,255,255,.14)}
.g-main{padding:14px 16px 4px;display:flex;flex-direction:column;gap:2px}
.g-main small{font-size:12px;color:rgba(255,255,255,.72)}
.g-main strong{font-size:24px;font-weight:400;line-height:1.2}
.g-modules{display:flex;gap:28px;padding:10px 16px 2px}
.g-modules small{display:block;font-size:11px;color:rgba(255,255,255,.66)}
.g-modules b{display:block;font-size:15px;font-weight:500}
.g-code{background:#fff;border-radius:12px;padding:12px 12px 6px;display:flex;flex-direction:column;align-items:center;gap:4px}
.pass-google .g-body small{color:#141414}
.g-band{
  background:var(--card-bg);color:var(--card-fg);padding:15px 16px 17px;
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
}
.g-issuer{display:flex;align-items:center;gap:10px;min-width:0}
.g-issuer img{width:28px;height:28px;border-radius:999px;object-fit:cover;background:#fff;flex-shrink:0}
.g-issuer span{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.g-points{display:flex;flex-direction:column;align-items:flex-end;gap:3px;flex-shrink:0}
.g-points span{font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;opacity:.78}
.g-points strong{font-size:24px;font-weight:500;line-height:1}
.g-hero{display:block;width:100%}
.g-body{padding:20px 16px 14px;display:flex;flex-direction:column;align-items:center;gap:8px}
.g-row{
  width:100%;margin-top:8px;display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  border-top:1px solid rgba(0,0,0,.09);padding-top:11px;
}
.g-row span{font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#5F6368}
.g-row b{font-size:14px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.a-code img,.g-qr{width:126px;height:126px;display:block;border-radius:2px}
.a-code small,.g-body small{
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:10.5px;letter-spacing:.11em;color:#141414;
}

/* Distribution kit on the owner's Card screen. */
.kit{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4)}
.kit-item{
  display:flex;flex-direction:column;gap:var(--s2);padding:var(--s4);
  border:1px solid var(--hair);border-radius:var(--r-control);background:rgba(255,255,255,.012);
}
.kit-item .icon{color:var(--brass)}
.kit-item strong{font-size:14px}
.kit-item span{font-size:13px;color:var(--ink-3)}
.share-qr{
  display:block;width:180px;max-width:100%;margin:0 auto;padding:12px;
  border-radius:var(--r-control);background:#fff;
  box-shadow:0 18px 40px -26px rgba(0,0,0,.9);
}
.share-link{display:block;margin-top:var(--s3);text-align:center;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12px;overflow-wrap:anywhere}

/* ---------- Cashier: the largest targets in the system -------------------- */
.cashier-shell{max-width:520px;margin:0 auto;padding:var(--s5) 20px var(--s6)}
.cashier-top{display:flex;align-items:center;gap:var(--s3);margin-bottom:var(--s5)}
.cashier-top .avatar{width:44px;height:44px}
.cashier-who{display:block;font-size:15px;font-weight:600;color:var(--ink)}
.cashier-where{display:block;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}

.scan-cta{width:100%;min-height:64px;font-size:17px;border-radius:var(--r-card)}
.scan-cta .icon{width:24px;height:24px}
.scan-hint{margin:var(--s3) 0 0;text-align:center;font-size:13px;color:var(--ink-3)}
.manual-entry{display:flex;gap:var(--s3);margin-top:var(--s5)}
.manual-entry input{font-family:'JetBrains Mono',ui-monospace,monospace;letter-spacing:.06em}

.card-customer{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s4)}
.card-customer h2{margin:var(--s1) 0 0;font-size:24px;font-weight:600;letter-spacing:-.02em}
.balance-display{text-align:right;flex-shrink:0}
.balance-display strong{
  display:block;font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:36px;font-weight:400;line-height:1.1;letter-spacing:-.03em;color:var(--brass);
}
.balance-display span{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}

.stamp-progress{display:flex;gap:var(--s2);flex-wrap:wrap;margin:var(--s5) 0}
.stamp-progress span{
  width:30px;height:30px;border-radius:999px;border:1px solid var(--hair-hard);
  display:grid;place-items:center;color:var(--ink-4);
  transition:background var(--t-state),border-color var(--t-state);
}
.stamp-progress span.filled{
  background:linear-gradient(180deg,var(--brass),var(--brass-deep));
  border-color:var(--brass-deep);color:var(--on-brass);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4);
  animation:stamp-in var(--t-enter) both;
}
@keyframes stamp-in{from{opacity:0;transform:scale(.7)}}

/* One customer: a few facts as label / value rows, then the edit form. */
.facts{list-style:none;margin:0 0 var(--s4);padding:0;display:grid;gap:6px}
.facts li{display:flex;justify-content:space-between;gap:var(--s3);font-size:14.5px;
  padding:6px 0;border-bottom:1px solid var(--hair)}
.facts span{color:var(--ink-3)}
.row-link{color:inherit;text-decoration:none}
.row-link:hover strong{text-decoration:underline}
fieldset.field{border:0;margin:0 0 var(--s3);padding:0}
fieldset.field legend{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 var(--s2);padding:0}
label.check{display:flex;align-items:center;gap:8px;text-transform:none;letter-spacing:0;font-size:14.5px;
  font-weight:500;color:var(--ink);margin:0 0 6px}
label.check input{width:18px;height:18px;margin:0}

/* Pro features carry a small brass tag wherever they are named. */
.pro-tag{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:6px;font-size:10px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;vertical-align:middle;color:var(--on-brass);
  background:linear-gradient(180deg,var(--brass),var(--brass-deep))}
.pro-note{margin:0;font-size:13px;color:var(--brass)}

/* The prepaid package sits under the stamps as its own small ledger: what is
   left in the brass mono of the balance, then use and sell. */
.package-panel{display:grid;gap:var(--s3);margin:0 0 var(--s5);padding:var(--s4);
  border:1px solid var(--hair-hard);border-radius:var(--r-card)}
.package-panel[hidden]{display:none}
.package-balance{display:flex;flex-direction:column;gap:2px}
.package-balance strong{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:30px;font-weight:400;
  line-height:1.1;letter-spacing:-.03em;color:var(--brass)}
.package-panel > button{min-height:56px;font-size:16px;width:100%}
.package-sell{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s2)}
.package-sell[hidden]{display:none}
.package-sell button{min-height:48px;white-space:nowrap}

/* Mobile commit bar: the brass action, full width, at the end. */
.cashier-actions{
  position:sticky;bottom:0;display:grid;gap:var(--s3);
  margin:var(--s5) -20px 0;
  padding:var(--s4) 20px calc(var(--s4) + env(safe-area-inset-bottom));
  background:rgba(17,19,22,.86);
  backdrop-filter:blur(20px) saturate(1.2);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  border-top:1px solid var(--hair);
}
.cashier-actions button{min-height:64px;font-size:16px;width:100%}
.cashier-actions .ghost{min-height:44px}
.cashier-actions label{margin-bottom:var(--s1)}

video{width:100%;border-radius:var(--r-card);max-height:380px;background:#000;border:1px solid var(--hair-hard)}
#camera-area{margin-top:var(--s4)}
#camera-area button{width:100%;margin-top:var(--s3)}

/* Till keypad. No card beside it, so the column is the panel alone. */
.auth-solo .auth-layout{grid-template-columns:minmax(0,1fr);max-width:440px}

.keypad{display:flex;flex-direction:column;align-items:center;gap:var(--s4)}
.keypad-dots{display:flex;gap:16px}
.keypad-dots i{
  width:12px;height:12px;border-radius:999px;
  border:1px solid var(--hair-hard);
  transition:background var(--t-state),border-color var(--t-state);
}
.keypad-dots i.on{background:var(--brass);border-color:var(--brass)}
/* One width for the pad and the button under it: they are a single control,
   and a wide button beneath a narrow pad reads as two unrelated things. Each
   tier below re-points this token instead of setting max-width twice. */
.auth-solo{--pad-width:300px}
.keypad-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;width:100%;max-width:var(--pad-width)}
.keypad-grid button{
  min-height:58px;padding:0;
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:22px;font-weight:400;letter-spacing:0;
}
.keypad-grid button:active{background:var(--brass-wash);border-color:var(--brass-deep)}
.keypad-grid [data-keypad]{font-size:17px;color:var(--ink-3)}

/* The till's button belongs to the pad: same width, directly under it, so the
   thumb travels straight down from the keys. Height only where there is room;
   the short tiers below claw it back. */
/* One class deeper than `.auth-panel .form-actions .smoky{width:auto}` further
   down the file, which otherwise wins on equal specificity by coming later. */
.auth-solo .auth-panel .form-actions{max-width:var(--pad-width);margin-inline:auto;width:100%}
.auth-solo .auth-panel .form-actions .smoky{width:100%}
@media(min-height:701px),(min-width:1081px) and (min-height:600px){
  .auth-solo .auth-panel .form-actions .smoky{min-height:64px}
  .auth-solo .auth-panel .form-actions .smoky-face{font-size:18px;padding:18px 24px}
}

/* A 3x4 pad is the tallest thing in the app, so it gives ground in steps.
   44px is the floor for a key: below that it stops being a touch target,
   and this screen is used with a thumb over a counter. */
@media(max-height:900px),(min-width:1081px) and (max-height:1125px){
  .keypad{gap:var(--s3)}
  .keypad-grid{gap:9px}
  .keypad-grid button{min-height:52px;font-size:20px}
}
@media(max-height:700px),(min-width:1081px) and (max-height:875px){
  .auth-solo{--pad-width:270px}
  .keypad-grid{gap:8px}
  .keypad-grid button{min-height:46px;font-size:19px}
}
/* The second half of each pair is the same threshold in a zoomed window: above
   1081px everything is drawn 1.25x, so a real 750px of glass is 600px of room.
   Media queries only ever see the real number. */
@media(max-height:600px),(min-width:1081px) and (max-height:750px){
  .keypad{gap:10px}
  .auth-solo{--pad-width:250px}
  .keypad-grid{gap:7px}
  .keypad-grid button{min-height:44px;font-size:18px}
  /* The label duplicates the field's own heading; the dots say the rest. */
  .keypad>.eyebrow{display:none}
}

/* A phone held upright has height to spare once the card is gone, and this is
   the screen someone taps a few hundred times a shift. Take the room: the pad
   spans the whole panel and the keys grow. Ordered after the tiers above so it
   overrides them, and gated on height so short phones keep their smaller keys. */
@media(max-width:1350px) and (min-height:701px) and (orientation:portrait){
  .keypad{gap:var(--s4)}
  .auth-solo{--pad-width:none}
  .keypad-grid{gap:12px}
  .keypad-grid button{min-height:68px;font-size:26px}
  .keypad-grid [data-keypad]{font-size:20px}
  .keypad-dots i{width:14px;height:14px}
}


.pin-input{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:30px;letter-spacing:18px;text-align:center;min-height:64px;padding-left:18px}

/* ---------- Auth ---------------------------------------------------------- */
.auth-main{display:flex;align-items:center;justify-content:center;padding:var(--s7) var(--gutter)}
/* Frosted glass has nothing to refract on a flat wall -- it degrades into a
   plain translucent rectangle, so the auth pages turn the page's own two
   light sources up and move one behind the panel. Same layer, same z-index:-1
   as everywhere else, which is what keeps it under the footer rather than
   washing over it. */
body:has(.auth-main)::before{
  /* Measured, not guessed: with sign-in filling the viewport the panel's
     centre lands at 66-73% across and ~52% down on every desktop size tried,
     so the warm source goes there. A glow anywhere else leaves the glass with
     nothing to refract, which is exactly how it was invisible before. */
  background:
    radial-gradient(calc(48 * var(--vw)) calc(52 * var(--vh)) at 70% 50%,rgba(201,169,106,.24),transparent 64%),
    radial-gradient(calc(44 * var(--vw)) calc(48 * var(--vh)) at 14% 74%,rgba(110,140,200,.17),transparent 64%),
    radial-gradient(calc(36 * var(--vw)) calc(40 * var(--vh)) at 30% 10%,rgba(201,169,106,.11),transparent 62%);
}
/* Below 1080px the two columns stack and the panel drops to roughly 50% / 69%,
   so the warm source has to follow it down. */
@media(max-width:1350px){
  body:has(.auth-main)::before{
    background:
      radial-gradient(calc(90 * var(--vw)) calc(60 * var(--vh)) at 50% 70%,rgba(201,169,106,.22),transparent 65%),
      radial-gradient(calc(80 * var(--vw)) calc(46 * var(--vh)) at 20% 14%,rgba(110,140,200,.15),transparent 62%);
  }
}
/* Sign-in drops the footer, so main must claim the rest of the viewport --
   otherwise it is only as tall as its content and the centred form rides up
   under the topbar instead of sitting in the middle of the screen. */
body:has(.auth-full){display:flex;flex-direction:column;height:calc(100 * var(--svh))}
.auth-full{flex:1 1 auto;min-height:0}
/* Sign-in has to fit the screen: two fields and a button should never need a
   scroll to reach. The panel keeps its natural height and the card -- the only
   elastic thing on the page -- takes whatever is left, deriving its width from
   its own aspect ratio rather than the other way round.

   svh, not vh: on iOS and Android vh is the height with the browser's address
   bar collapsed, which is taller than what you can actually see on load. */
.auth-full .auth-layout{max-height:100%;min-height:0}

@media(max-width:1350px){
  .auth-full{padding-block:clamp(12px,2.5 * var(--svh),var(--s7))}
  .auth-full .auth-layout{
    grid-template-rows:minmax(0,auto) auto;
    gap:clamp(14px,2.5 * var(--svh),var(--s6));
  }
  .auth-full .hero-stage{min-height:0;padding:0;display:flex;align-items:center;justify-content:center}
  /* Stacked, the panel is a grid item stretched across a row far wider than
     its own 440px cap, so it parks against the left edge. Centre it. */
  .auth-full .auth-panel{width:100%;margin-inline:auto}
  /* Stacked, the card and the panel are one column: same width, same centre
     line. Both cap at 440px, so they line up instead of the card sitting in
     from the edges. Height then comes from aspect-ratio -- which is why the
     room has to be found in the padding below, not by shrinking the card. */
  .auth-full .tilt{width:100%;max-width:440px;margin-inline:auto}
}

/* Short screens. The card is no longer allowed to shrink -- it has to keep the
   panel's width -- so the space comes out of padding and vertical rhythm.
   Input heights are deliberately untouched: they are the touch targets.

   The card still needs this at 700px, but the panel does not: sign-in is two
   fields and a button, and squeezing it this early made a roomy monitor look
   cramped. Panel compression starts at 560 instead, below. */
@media(max-height:700px){
  .auth-full{padding-block:10px}
  .auth-full .auth-layout{gap:12px}
  .auth-solo .auth-panel{padding:20px}
  .auth-solo .auth-panel h2{margin:2px 0 14px}
  .auth-solo .field{margin-bottom:12px}
  .auth-solo .form-actions{margin-top:16px}
}
@media(max-height:600px),(min-width:1081px) and (max-height:750px){
  body:has(.auth-full) .topbar{min-height:48px}
  .auth-full{padding-block:10px}
  /* Only the till gives up its label and its rhythm here. Its keypad needs
     every pixel; sign-in still has room to spare at this height, and dropping
     the label there made the panel look truncated on a roomy monitor. */
  .auth-solo .auth-panel{padding:14px 20px}
  .auth-solo .auth-panel .eyebrow{display:none}
  .auth-solo .auth-panel h2{margin:0 0 10px;font-size:18px}
  .auth-solo .field{margin-bottom:8px}
  .auth-solo .form-actions{margin-top:10px}
}
/* Phones do need it at 700: there the card sits above the panel and the two
   together fill the screen. A wide window at the same height has the card
   beside the panel and plenty of slack, which is the case this guards. */
@media(max-height:700px) and (max-width:1080px){
  .auth-full .auth-panel{padding:20px}
  .auth-full .auth-panel h2{margin:2px 0 14px}
  .auth-full .field{margin-bottom:12px}
  .auth-full .form-actions{margin-top:16px}
}
/* Sign-in's own floor: only once the window is genuinely small. */
@media(max-height:560px){
  .auth-full .auth-panel{padding:16px 20px}
  .auth-full .auth-panel .eyebrow{display:none}
  .auth-full .auth-panel h2{margin:0 0 12px;font-size:19px}
  .auth-full .field{margin-bottom:10px}
  .auth-full .form-actions{margin-top:12px}
}
/* A 360px-tall window is still short of the tier above. What is left to give
   is padding and the heading's weight, not the keys. */
@media(max-height:420px),(min-width:1081px) and (max-height:525px){
  body:has(.auth-full) .topbar{min-height:44px}
  .auth-full{padding-block:6px}
  .auth-full .auth-panel{padding:8px 16px}
  .auth-full .keypad{gap:6px}
  .auth-full .keypad-grid{gap:5px}
  .auth-full .auth-panel h2{font-size:15px;margin-bottom:4px}
  .auth-full .field{margin-bottom:6px}
  .auth-full .form-actions{margin-top:6px}
}
/* A phone lying sideways is the one place the 44px floor cannot hold: the pad,
   a heading and a button simply do not fit in 360px of glass. 40px is still a
   deliberate target, and losing the heading would cost more than 4px a key. */
@media(max-height:380px){
  .auth-full{padding-block:2px}
  .auth-full .auth-panel{padding:6px 16px}
  .auth-full .auth-panel h2{font-size:14px;margin-bottom:2px}
  .auth-full .keypad-grid button{min-height:40px;font-size:17px}
  .auth-full .keypad-grid{gap:4px}
  .auth-full .keypad-dots{gap:12px}
  .auth-full .keypad-dots i{width:10px;height:10px}
}

/* Under ~600px of height the formula leaves the card below about 180px wide,
   where the engraving is no longer legible and it reads as a smudge. Drop it
   and let the form have the screen: it is the reason the page exists. */
@media(max-width:1350px) and (max-height:600px){
  .auth-full .hero-stage{display:none}
}

/* On a phone the card is decoration in front of the only thing the page is
   for. Somebody arriving here wants the form, not a picture of a card they
   have not got yet. */
@media(max-width:760px){
  .auth-intro{display:none}
  .auth-full .auth-layout{grid-template-columns:minmax(0,1fr);max-width:440px;margin-inline:auto}
}

/* Wide but short. Stacking needs vertical room this window does not have, so
   the two columns come back rather than the card being squeezed to nothing. */
@media(min-width:1081px) and (max-height:900px){
  /* Not on the till: that page has no card, so the second column would be
     empty and the panel would sit off to the left of it. */
  .auth-full:not(.auth-solo) .auth-layout{grid-template-columns:1.05fr .95fr;grid-template-rows:auto}
}
.auth-layout{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(40px,calc(7 * var(--vw)),110px);align-items:center;width:100%;max-width:1120px}
.auth-intro h1{margin:var(--s4) 0;max-width:14ch}
.auth-intro p{font-size:17px;max-width:42ch}
.auth-panel{padding:var(--s6);max-width:440px;border-radius:var(--r-sheet);box-shadow:var(--e3)}
/* Only where the blur actually exists. Without the guard a browser that
   cannot blur would keep the near-transparent fill and drop the form's text
   straight onto the aura; here it simply keeps .panel's solid surface. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .auth-panel{
    border:0;border-top:1px solid rgba(255,255,255,.14);border-radius:20px;
    background:rgba(255,255,255,.03);box-shadow:none;
    -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  }
}
.auth-panel h2{margin:var(--s3) 0 var(--s5);font-size:24px}
.auth-panel .form-actions button{width:100%}
.decor-stamps{display:flex;gap:10px;margin-top:var(--s6);flex-wrap:wrap}
.decor-stamps span{
  width:40px;height:40px;display:grid;place-items:center;border-radius:999px;
  background:var(--brass-wash);border:1px solid rgba(201,169,106,.3);color:var(--brass);box-shadow:var(--e1);
}
.decor-stamps span:last-child{background:transparent;border-style:dashed;border-color:var(--hair-hard);color:var(--ink-4)}

/* ---------- Plain top bar (cashier, public) ------------------------------- */
.topbar{
  position:sticky;top:0;z-index:40;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  min-height:64px;padding:0 20px;
  background:rgba(17,19,22,.72);
  backdrop-filter:blur(20px) saturate(1.2);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  border-bottom:1px solid var(--hair);
}
.top-actions{display:flex;align-items:center;gap:var(--s2)}
.business-label{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}

/* ---------- Language picker ----------------------------------------------- */
.language-picker{position:relative;flex-shrink:0}
.language-picker summary{
  display:flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:44px;min-width:56px;padding:0 var(--s3);
  border-radius:var(--r-control);cursor:pointer;list-style:none;transition:background var(--t-state);
}
.language-picker summary::-webkit-details-marker{display:none}
.language-picker summary:hover,.language-picker[open] summary{background:rgba(255,255,255,.05)}
.language-picker img{display:block;width:22px;height:15px;border-radius:2px;box-shadow:0 0 0 1px rgba(255,255,255,.16)}
.language-options{
  position:absolute;right:0;top:calc(100% + var(--s2));
  width:200px;padding:var(--s1);
  border:1px solid var(--hair-hard);border-radius:var(--r-card);
  background:rgba(21,23,27,.96);
  backdrop-filter:blur(20px) saturate(1.2);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  box-shadow:var(--e3);z-index:50;
  animation:fade-in var(--t-state);
}
/* Fade only: nothing clickable animates its own position. */
@keyframes fade-in{from{opacity:0}}
.rail-actions .language-options{top:auto;bottom:calc(100% + var(--s2));right:auto;left:0}
.language-options a{
  display:flex;align-items:center;gap:var(--s3);
  min-height:44px;padding:0 var(--s3);border-radius:var(--r-control);
  color:var(--ink-2);font-size:14px;font-weight:500;
  transition:background var(--t-state),color var(--t-state);
}
.language-options a:hover{background:rgba(255,255,255,.05);color:var(--ink)}
.language-options a[aria-current=true]{background:var(--brass-wash);color:var(--brass)}
.logout-form{margin:0;display:flex}

/* ---------- Overlays ------------------------------------------------------ */
#toast{
  position:fixed;left:50%;bottom:var(--s5);transform:translateX(-50%);
  display:flex;align-items:center;gap:var(--s3);
  padding:14px 20px;max-width:calc(92 * var(--vw));z-index:100;
  border:1px solid var(--hair-hard);border-radius:var(--r-card);
  background:rgba(21,23,27,.94);
  backdrop-filter:blur(20px) saturate(1.2);
  -webkit-backdrop-filter:blur(20px) saturate(1.2);
  box-shadow:var(--e3);font-size:14px;color:var(--ink);
  animation:fade-in var(--t-enter);
}
#toast.error{border-color:rgba(228,115,107,.35);color:#F0ABA2}

dialog{
  padding:var(--s6);max-width:520px;width:calc(100% - 40px);
  border:1px solid var(--hair-hard);border-radius:var(--r-sheet);
  background:linear-gradient(180deg,var(--surface-hi),var(--surface-lo));
  color:var(--ink);box-shadow:var(--e3);
}
dialog::backdrop{background:rgba(6,7,8,.72);backdrop-filter:blur(20px) saturate(1.2)}
dialog[open]{animation:sheet-in var(--t-surface)}
@keyframes sheet-in{from{opacity:0;transform:scale(.98)}}
dialog h2{font-size:24px}
.dialog-close{position:absolute;right:14px;top:14px;width:44px;height:44px;padding:0;border-color:transparent;background:transparent;color:var(--ink-3);box-shadow:none}
.dialog-close:hover{background:rgba(255,255,255,.06);color:var(--ink)}
#result-body a{display:block;overflow-wrap:anywhere;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:13px}
#result-body strong{display:block;text-align:center;font-family:'JetBrains Mono',ui-monospace,monospace;font-size:34px;letter-spacing:.18em;color:var(--brass);margin:var(--s4) 0}
#result-body img{display:block;width:180px;margin:var(--s4) auto;padding:12px;border-radius:var(--r-control);background:#fff}

footer{
  padding:var(--s5) var(--gutter) var(--s6);
  border-top:1px solid var(--hair);
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);text-align:center;
}
footer span{padding:0 var(--s2);opacity:.5}

.back-link{display:inline-flex;align-items:center;gap:var(--s2);min-height:44px;font-size:13px;color:var(--ink-3)}
.back-link:hover{color:var(--ink)}
.back-link .icon{width:16px;height:16px}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
[hidden]{display:none!important}


/* ============================================================================
   Sign-in hero: a loyalty card on a perspective stage, and the smoky button.
   Both are decoration — the page works with neither.
   ========================================================================= */

.hero-stage{
  perspective:900px;
  display:flex;align-items:center;justify-content:center;
  padding:var(--s5) 0;
}
.tilt{
  /* The wrapper carries the width. Without it the card's `100%` resolves
     against its own content, so every translation produced a different size. */
  width:min(420px,100%);
  transform-style:preserve-3d;
  transition:transform .15s ease-out;
  will-change:transform;
}

.hero-card{
  position:relative;
  /* The card is an object, not a document: dragging across it should never
     leave a blue smear over the brand mark. */
  -webkit-user-select:none;user-select:none;
  width:100%;
  min-width:0;
  aspect-ratio:420 / 265;
  /* Nothing inside may change the card's size: it is a card, not a paragraph. */
  overflow:hidden;
  padding:18px 24px;
  display:flex;flex-direction:column;justify-content:space-between;
  border:1px solid rgba(201,169,106,.18);
  border-radius:20px;
  background:linear-gradient(145deg,#1B1E22 0%,#121518 35%,#1A160D 65%,#16191C 100%);
  box-shadow:
    0 25px 60px rgba(0,0,0,.5),
    0 8px 24px rgba(0,0,0,.3),
    inset 0 1px 0 rgba(255,255,255,.06);
  transform-style:preserve-3d;
}

.card-holo,.card-shine{position:absolute;inset:0;pointer-events:none;z-index:0}
.card-holo{
  background:linear-gradient(
    var(--holo-angle,135deg),
    transparent 0%,
    rgba(201,169,106,.05) 25%,
    rgba(224,196,140,.10) 40%,
    rgba(201,169,106,.07) 50%,
    rgba(201,169,106,.04) 60%,
    transparent 80%);
  mix-blend-mode:screen;
  transition:background .15s ease-out;
}
.card-shine{
  inset:-50%;width:200%;height:200%;
  background:radial-gradient(
    circle at var(--shine-x,50%) var(--shine-y,-20%),
    rgba(255,255,255,.09) 0%,
    rgba(255,255,255,.035) 20%,
    transparent 50%);
  transition:background .15s ease-out;
}
/* Content sits above both layers. */
.hero-card>*:not(.card-holo):not(.card-shine){position:relative;z-index:1}

.hero-card-top{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);min-width:0}
.hero-brand{display:flex;align-items:center;gap:9px;color:var(--brass);min-width:0}
.hero-brand span{font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);white-space:nowrap}
.hero-tag{
  padding:5px 10px;border-radius:999px;white-space:nowrap;
  border:1px solid rgba(201,169,106,.26);background:rgba(201,169,106,.08);
  font-size:9px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--brass);
}

.hero-stamps{display:flex;gap:8px;flex-wrap:nowrap}
.hero-stamps i{
  width:20px;height:20px;flex:0 0 auto;
  border-radius:999px;border:1px solid rgba(201,169,106,.35);
}
.hero-stamps i.on{
  background:linear-gradient(180deg,var(--brass),var(--brass-deep));
  border-color:var(--brass-deep);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4);
}

.hero-engraving{width:100%;min-height:0;flex:1;display:flex;align-items:center;justify-content:center;pointer-events:none}
.hero-engraving img{display:block;width:100%;height:auto;max-height:146px;object-fit:contain}
.hero-card-bottom{display:flex;align-items:flex-end;justify-content:flex-end;gap:var(--s3);min-width:0}
.hero-card-bottom>span{min-width:0;overflow:hidden}
.hero-card-bottom small{
  display:block;font-size:9px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;
}
.hero-card-bottom strong{
  display:block;margin-top:3px;white-space:nowrap;
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:20px;font-weight:400;letter-spacing:-.02em;color:var(--ink);
}
.hero-live{
  display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--brass);
}
.hero-live::before{content:'';width:5px;height:5px;border-radius:999px;background:var(--brass)}

/* ---------- Smoky sign-in button ------------------------------------------ */
/* A direct port of the reference markup: canvas at -16px behind, clipped by
   the button, with a translucent plate 2px inside it. Only the shader colours
   differ. The button stays plain brass until the shader really starts, so a
   visitor without JavaScript or WebGL still gets a readable control. */
.smoky{
  position:relative;
  isolation:isolate;
  display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;text-decoration:none;
  overflow:hidden;
  border-radius:14px;
  padding:0;
  border:0;
  background:none;
  box-shadow:none;
  font-size:16px;
  font-weight:500;
  min-height:0;
}
.smoky-bg{position:absolute;inset:-16px;z-index:-1;opacity:0;transition:opacity .4s ease}
.smoky-bg canvas{
  position:absolute;top:0;left:0;width:100%;height:100%;
  transition:transform .3s ease;
}
.smoky-face{
  display:block;
  flex:1 1 auto;
  margin:2px;
  padding:10px 24px;
  border-radius:12px;
  background:var(--brass);
  color:var(--on-brass);
  transition:background .3s ease,color .3s ease;
}

/* Only once the shader is live. */
.smoky.on .smoky-bg{opacity:1}
.smoky.on .smoky-face{background:rgba(0,0,0,.5);color:rgba(255,255,255,.8)}
.smoky.on:hover .smoky-face{background:rgba(0,0,0,.25);color:#fff}
.smoky.on:hover .smoky-bg canvas{transform:scale(1.2) rotate(10deg)}

.auth-panel .form-actions{justify-content:center}
.auth-panel .form-actions .smoky{width:auto}

@media(prefers-reduced-motion:reduce){
  .card-shine{animation:none}
  .smoky.on:hover .smoky-bg canvas{transform:none}
  .tilt{transition:none}
  .smoke-on:hover .smoke-layer canvas{transform:none}
}

@media(max-width:760px){
  .card-holo{display:none}
  .card-shine{
    inset:0;width:100%;height:100%;
    background:linear-gradient(105deg,
      transparent 0%,transparent 35%,
      rgba(255,255,255,.06) 45%,
      rgba(255,255,255,.11) 50%,
      rgba(255,255,255,.06) 55%,
      transparent 65%,transparent 100%) 0 0/200% 100%;
    animation:card-sweep 4s ease-in-out infinite;
  }
  @keyframes card-sweep{from{background-position:200% 0}to{background-position:-200% 0}}
  .hero-stage{perspective:700px;padding:var(--s3) 0}
  .hero-card{padding:18px 20px;border-radius:16px}
  .hero-stamps i{width:15px;height:15px}
  .hero-stamps{gap:6px}
  .hero-card-bottom strong{font-size:17px}
  .auth-panel .form-actions .smoke-button{width:100%}
}

/* ---------- Responsive ---------------------------------------------------- */
/* Breakpoints carry the same 1.25 factor as the zoom. Media queries are
   evaluated against the real viewport, not the zoomed layout box, so leaving
   it at 1080 would keep the two-column desktop layout alive in a window that,
   once zoomed, no longer has desktop room: 1080 -> 1350. The 760px phone
   breakpoint is untouched, because below 1081px the zoom is off. */
@media(max-width:1350px){
  /* A bare 1fr track still takes its minimum from the content, so the rail
     could grow past the phone. minmax(0,1fr) caps it at the viewport. */
  .shell{grid-template-columns:minmax(0,1fr)}
  .rail{
    position:sticky;top:0;z-index:40;height:auto;min-height:0;
    /* The desktop rail scrolls; this bar must not, or it clips the "more"
       sheet that hangs out of it (the blur makes the bar its container). */
    overflow:visible;
    flex-direction:row;align-items:center;gap:var(--s4);
    padding:10px 20px;border-right:0;border-bottom:1px solid var(--hair);
  }
  .rail .brand{padding:0}
  .brand-word{display:none}
  /* min-width:0 lets the scroller shrink; without it the seven links set a
     floor wider than the phone and pushed the actions off screen. */
  .rail-nav{flex-direction:row;gap:var(--s1);overflow-x:auto;flex:0 1 auto;min-width:0}
  /* Below the desktop rail the strip is a single row, and seven labelled links
     do not fit in it. The last three move behind "more" -- the same sheet the
     phone uses, hung under the bar instead of over the thumb. */
  .rail-more:not([hidden]){
    display:inline-flex;align-items:center;gap:var(--s2);flex-shrink:0;
    min-height:44px;margin:0;padding:0 12px;border:0;border-radius:var(--r-control);
    background:transparent;box-shadow:none;color:var(--ink-3);
    font-size:14px;font-weight:500;letter-spacing:0;text-transform:none;
  }
  .rail-more .icon{color:var(--ink-4)}
  .rail-more[aria-expanded=true]{color:var(--ink);background:rgba(255,255,255,.05)}
  .rail-more[aria-expanded=true] .icon{color:var(--brass)}
  .rail-rest{display:none}
  .rail-rest[data-open]{
    display:flex;flex-direction:column;gap:var(--s3);
    position:absolute;top:calc(100% + 6px);right:12px;left:auto;
    width:min(300px,calc(100vw - 24px));
    padding:var(--s4);border:1px solid var(--hair-hard);border-radius:16px;
    background:var(--chrome);box-shadow:0 26px 60px rgba(0,0,0,.5);
    animation:sheet-in var(--t-surface) ease-out;
  }
  @keyframes sheet-in{from{opacity:0;transform:translateY(-8px)}}
  .rail-nav-rest{flex:0 0 auto;flex-direction:column;gap:2px;overflow:visible}
  .rail-nav-rest .rail-link{flex-shrink:0;min-height:44px}
  .rail-foot{flex-direction:column;align-items:stretch;margin:0;padding-top:var(--s3);padding-bottom:0;border-top:1px solid var(--hair);position:static;background:transparent}
  .rail-tenant{display:flex}
  .rail-actions{justify-content:space-between}
  .rail-actions .logout-form>button span{display:inline}
  .rail-link{flex-shrink:0;padding:0 10px}
  .rail-actions .language-options{top:calc(100% + var(--s2));bottom:auto;right:0;left:auto}
  .container{padding:var(--s6) 20px var(--s7)}
  .metrics{grid-template-columns:repeat(2,1fr)}
  .ratios{grid-template-columns:1fr;gap:var(--s4)}
  .kit{grid-template-columns:1fr}
  .auth-layout{grid-template-columns:1fr;gap:var(--s6)}
  .auth-main{padding:var(--s6) 20px}
}

@media(max-width:760px){
  :root{--gutter:20px;--pad-card:18px}
  h1{font-size:30px}
  h2{font-size:22px}
  .display{font-size:36px}
  .page-heading{flex-direction:column;align-items:flex-start;gap:var(--s4)}
  .head-actions{width:100%}
  .head-actions button,.head-actions .button{flex:1}
  .panel>.head-actions,.notify-way>.head-actions{flex-wrap:wrap}
  .split,.split-wide{grid-template-columns:1fr;gap:var(--s4)}
  .metric-value{font-size:32px}
  .form-actions{flex-direction:column-reverse;align-items:stretch}
  .form-actions button{width:100%}
  .auth-panel{padding:var(--s5);max-width:100%}
  input,textarea,select{font-size:16px}
  footer{padding:var(--s5) 20px}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

/* ---------- Public pages: landing and legal ----------------------------- */
/* Read once by a stranger deciding whether to trust the product, so the
   measure stays narrow and the rhythm is generous. Reuses the app's tokens
   rather than a second identity. */
.public-main{display:block;padding:var(--s4) var(--gutter) var(--s7)}
.public-main>*{max-width:960px;margin-inline:auto}
/* The card leads. It is the product, and one glance at it says more than a
   paragraph would -- so the copy beside it stays short. */
.landing-hero{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(28px,5vw,72px);align-items:center;padding:var(--s2) 0 var(--s6)}
/* The hero owns the first screen. Without this it ends early and the next
   section's heading pokes in under the fold, which reads as a mistake rather
   than as an invitation to scroll. --vh, not vh: the desktop zoom leaves raw
   viewport units unscaled. 64px is the top bar. */
/* The hero owns the first screen and sits centred in it, the way the sign-in
   page centres its card and panel: align-content moves the row, align-items
   still centres the card against the taller copy column. Without this the next
   section's heading pokes in under the fold and reads as a mistake. */
.landing-hero{min-height:calc(100 * var(--svh) - 64px - var(--s4));align-content:center}
.landing-hero .hero-stage{padding:0}

/* ---------- Landing hero phone ---------------------------------------------
   A phone at a three-quarter turn, holding the demo shop's real pass. The
   pose lives on the phone and the pointer tilt on .tilt, so the two add up
   instead of one replacing the other. Everything inside is sized in em off a
   font size tied to the phone's width, so a smaller phone is the same picture
   rather than the same text in less room. It is also capped by the screen's
   height: the whole phone belongs on the first screen. */
.hero-stage-phone{perspective:1000px}
.hero-stage-phone .tilt{width:min(288px,64vw,calc((100 * var(--svh) - 230px) * .46));container-type:inline-size}
.hero-phone{
  position:relative;aspect-ratio:9/19.2;padding:.8em;border-radius:3.9em;
  font-size:4.5cqw;
  -webkit-user-select:none;user-select:none;
  background:linear-gradient(150deg,#46494f 0%,#1a1c1f 38%,#2d3035 68%,#0f1012 100%);
  box-shadow:inset 0 0 0 1.5px #5b5f66,inset 0 0 0 3px #16181b,
    0 45px 90px rgba(0,0,0,.55),0 14px 34px rgba(0,0,0,.35);
  transform:rotateY(-18deg) rotateX(8deg) rotateZ(4deg);
  transform-style:preserve-3d;
}
/* The side of the phone: fourteen copies of the outline, each a hair further
   back, read as one titanium band once the phone is turned. */
.phone-edge{position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(90deg,#3b3e44 0%,#b9bec6 7%,#6d727a 22%,#4a4e55 50%,#6d727a 78%,#b9bec6 93%,#3b3e44 100%)}
.phone-edge:nth-of-type(1){transform:translateZ(-0.17em)}
.phone-edge:nth-of-type(2){transform:translateZ(-0.34em)}
.phone-edge:nth-of-type(3){transform:translateZ(-0.51em)}
.phone-edge:nth-of-type(4){transform:translateZ(-0.68em)}
.phone-edge:nth-of-type(5){transform:translateZ(-0.85em)}
.phone-edge:nth-of-type(6){transform:translateZ(-1.02em)}
.phone-edge:nth-of-type(7){transform:translateZ(-1.19em)}
.phone-edge:nth-of-type(8){transform:translateZ(-1.36em)}
.phone-edge:nth-of-type(9){transform:translateZ(-1.53em)}
.phone-edge:nth-of-type(10){transform:translateZ(-1.70em)}
.phone-edge:nth-of-type(11){transform:translateZ(-1.87em)}
.phone-edge:nth-of-type(12){transform:translateZ(-2.04em)}
.phone-edge:nth-of-type(13){transform:translateZ(-2.21em)}
.phone-edge:nth-of-type(14){transform:translateZ(-2.38em)}
.phone-edge:nth-of-type(15){transform:translateZ(-2.55em)}
.phone-edge:nth-of-type(16){transform:translateZ(-2.72em)}
.phone-edge:nth-of-type(17){transform:translateZ(-2.89em)}
.phone-edge:nth-of-type(18){transform:translateZ(-3.06em)}
.phone-edge:nth-of-type(18){background:#18191c;box-shadow:0 30px 60px rgba(0,0,0,.45)}
.phone-btn{position:absolute;width:.5em;border-radius:.2em;pointer-events:none;
  background:linear-gradient(90deg,#2b2e33,#8a8f97 50%,#2b2e33);transform:translateZ(-1.55em)}
.phone-btn-action{left:-.3em;top:15%;height:4.5%}
.phone-btn-up{left:-.3em;top:23%;height:8%}
.phone-btn-down{left:-.3em;top:33%;height:8%}
.phone-btn-power{right:-.3em;top:26%;height:12%}
.phone-screen{transform:translateZ(1px);
  position:relative;height:100%;overflow:hidden;border-radius:3.15em;
  padding:0 .85em;background:linear-gradient(180deg,#f4f4f7,#e9eaee);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Inter,sans-serif;color:#111;
}
.phone-status{position:relative;display:flex;align-items:center;justify-content:space-between;height:3.1em;padding:0 1.25em;font-size:1em;font-weight:600}
.phone-island{position:absolute;left:50%;top:.75em;width:6.3em;height:1.85em;margin-left:-3.15em;border-radius:1.1em;background:#000}
.phone-bars{display:flex;align-items:flex-end;gap:.15em;height:.77em}
.phone-bars i{width:.23em;border-radius:1px;background:#111}
.phone-bars i:nth-child(1){height:30%}.phone-bars i:nth-child(2){height:55%}
.phone-bars i:nth-child(3){height:78%}.phone-bars i:nth-child(4){height:100%}
.phone-note{
  position:relative;z-index:2;display:flex;gap:.7em;align-items:center;margin-top:.45em;padding:.7em .85em;
  border-radius:1.3em;background:rgba(255,255,255,.9);box-shadow:0 .6em 1.5em rgba(0,0,0,.14);
  transition:opacity .45s ease,transform .45s cubic-bezier(.2,.9,.3,1.25);
}
.phone-note img{flex:0 0 auto;width:2.6em;height:2.6em;border-radius:.7em}
.note-body{min-width:0;flex:1}
.note-head{display:flex;justify-content:space-between;gap:.4em;font-size:.88em;white-space:nowrap}
.note-head b{overflow:hidden;text-overflow:ellipsis}
.note-head span{color:#8a8a8e;font-size:.92em}
.phone-note p{margin:.1em 0 0;font-size:.88em;line-height:1.25;color:#222}
.phone-note.waiting{opacity:0;transform:translateY(-1.2em) scale(.96)}
/* The landing phone's pass only: unscoped, it repainted every card preview. */
.hero-phone .pass{margin-top:.8em;overflow:hidden;border-radius:1em;background:#ceb286;color:#4e321e;box-shadow:0 .6em 1.5em rgba(0,0,0,.18)}
.pass-head{display:flex;align-items:center;justify-content:space-between;padding:.8em .9em .6em}
.pass-head img{display:block;height:2.3em;width:auto}
.pass-field{white-space:nowrap}
.pass-field small{display:block;font-size:.66em;font-weight:600;letter-spacing:.04em;color:#1c3e2a}
.pass-field span{font-size:1em}
.pass-field.center{text-align:center}.pass-field.right{text-align:right}
.pass-strip{position:relative;aspect-ratio:375/144;overflow:hidden}
.pass-strip img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pass-strip [data-before]{opacity:0;transition:opacity .25s ease}
.pass-strip.before [data-before]{opacity:1}
.pass-strip.landed{animation:stamp-landed .45s ease}
@keyframes stamp-landed{40%{transform:scale(1.035)}}
.pass-fields{display:flex;justify-content:space-between;gap:.6em;padding:.6em .9em .45em}
.pass-qr{display:flex;flex-direction:column;align-items:center;padding:.45em 0 1.1em}
.pass-qr img{width:7.1em;height:7.1em;padding:.55em;border-radius:.45em;background:#fff;image-rendering:pixelated}
.pass-qr span{margin-top:.4em;font-size:.7em;opacity:.7}
@media(max-width:760px){
  .hero-stage-phone .tilt{width:min(236px,62vw)}
  .hero-phone{transform:rotateY(-13deg) rotateX(6deg) rotateZ(3deg)}
}
@media(prefers-reduced-motion:reduce){
  .phone-note,.pass-strip [data-before]{transition:none}
  .pass-strip.landed{animation:none}
}

/* ---------- Landing: the iOS 27 card in the phone -------------------------
   The phone above, dark the way Wallet is, holding the demo café's poster
   card and the two buttons iOS puts under it. Sized in em off the phone's
   width, so it scales as one picture. A touch larger than the phone's own
   cap, still small enough that the whole phone sits on the first screen. */
.hero-stage-poster .tilt{width:min(320px,72vw,calc((100 * var(--svh) - 110px) * .425))}
.hero-phone-dark .phone-screen{display:flex;flex-direction:column;gap:.42em;background:#000;color:#fff}
.hero-phone-dark .phone-bars i{background:#fff}
.hero-phone-dark .phone-island{background:#111}
.poster-card{position:relative;flex:none;margin-top:.2em;aspect-ratio:458/642;overflow:hidden;border-radius:1.1em;background:#140d09;
  box-shadow:0 .6em 1.6em rgba(0,0,0,.5)}
.pc-art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Frames swap at once: a fade lays two half-clear photos over each other,
   and for that moment the whole card looks soft. */
.pc-frame{opacity:0}
.pc-frame.shown{opacity:1}
.pc-logo{position:absolute;left:6.5%;top:1.4%;width:37%;height:auto}
.pc-code{position:absolute;left:50%;top:48%;width:41%;aspect-ratio:1;padding:3%;transform:translateX(-50%);border-radius:.4em;background:#fff}
.pc-code img{display:block;width:100%;height:100%;image-rendering:pixelated}
.pc-strip{position:absolute;left:0;right:0;bottom:0;height:20%;display:flex;align-items:center;justify-content:space-between;padding:0 6.5%;
  background:linear-gradient(180deg,rgba(70,45,32,.55),rgba(52,33,24,.92));-webkit-backdrop-filter:blur(.8em);backdrop-filter:blur(.8em)}
.pc-strip span{display:flex;flex-direction:column;gap:.15em;font-family:ui-monospace,"SF Mono","JetBrains Mono",monospace}
.pc-strip small{font-size:.58em;letter-spacing:.04em;color:rgba(255,226,204,.68)}
.pc-strip b{font-size:.82em;font-weight:500;color:#fff;white-space:nowrap}
.pc-strip .pc-right{text-align:right}
.pc-row{flex:none;display:flex;align-items:center;gap:.6em;padding:.55em .7em;border-radius:.9em;background:#1c1c1e}
.pc-row b{flex:1;font-size:.76em;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pc-info{flex-direction:column;align-items:flex-start;gap:.1em}
.pc-info small{font-size:.6em;color:rgba(255,255,255,.55)}
.pc-icon{flex:none;display:grid;place-items:center;width:1.55em;height:1.55em;border-radius:50%;background:#ff3b30;color:#fff}
.pc-icon .icon{width:.8em;height:.8em}
.pc-chev{font-size:1.1em;line-height:1;color:rgba(255,255,255,.35)}
@media(max-width:760px){
  .hero-stage-poster .tilt{width:min(250px,66vw)}
}
@media(prefers-reduced-motion:reduce){
}
}
.hero-copy{display:flex;flex-direction:column;gap:var(--s3)}
.hero-copy h1{max-width:16ch;margin:0;font-size:clamp(30px,3.6vw,44px)}
.hero-copy .lede{font-size:18px;max-width:46ch;color:var(--ink-2)}
.hero-actions{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--s3);margin-top:var(--s2)}
/* The same smoke as the sign-in button, sized for a landing call to action. */
.hero-smoky{min-height:52px;border-radius:14px;align-items:stretch}
.hero-smoky .smoky-face{display:flex;align-items:center;justify-content:center;
  padding:0 26px;font-size:16px;font-weight:600}
.hero-actions .button{min-height:52px;border-radius:14px;padding:0 22px;font-size:15px}
.hero-demo{display:contents}
.hero-actions .smoky{min-height:52px}
.closing p{max-width:58ch}
@media(max-width:1000px),(min-width:1081px) and (max-width:1250px){
  .landing-hero{grid-template-columns:minmax(0,1fr);gap:var(--s5)}
  .hero-copy h1{max-width:100%}
}

.public-section{display:flex;flex-direction:column;gap:var(--s4);padding:var(--s6) 0;
  border-top:1px solid var(--hair)}
.public-section h2{margin:0;font-size:24px}
.public-section p{max-width:64ch}

/* A real sequence, so it is numbered. */
.how{list-style:none;margin:0;padding:0;display:grid;gap:var(--s4);counter-reset:step;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.how li{counter-increment:step;display:flex;flex-direction:column;gap:6px;padding-top:var(--s3);
  border-top:2px solid var(--brass)}
.how li::before{content:counter(step);font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:12px;color:var(--brass)}
.how b{font-size:16px}
.how span{color:var(--ink-2);font-size:14.5px;line-height:1.6}

.feature-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--s4) var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.feature-list li{display:flex;flex-direction:column;gap:3px;color:var(--ink-2);font-size:14.5px}
.feature-list b{color:var(--ink);font-size:15.5px}

/* "Why us": the header link and the comparison. Our column carries the brass
   rule so the eye reads down it; the other column steps back. */
.top-link{font-size:14px;font-weight:600;color:var(--ink-2);text-decoration:none;padding:6px 10px;
  border-radius:10px;white-space:nowrap}
.top-link:hover,.top-link.selected{color:var(--ink);background:var(--hair)}
.why-head h1{margin:0;font-size:clamp(28px,4vw,42px);line-height:1.15;max-width:22ch}
.compare-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.compare{width:100%;border-collapse:collapse;font-size:14.5px;min-width:560px}
.compare th,.compare td{text-align:left;vertical-align:top;padding:12px 14px;border-bottom:1px solid var(--hair)}
.compare thead th{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.compare tbody th{color:var(--ink);font-weight:600;width:24%}
.compare td{color:var(--ink-3)}
.compare .us{color:var(--ink);border-left:2px solid var(--brass)}
.compare thead .us{color:var(--brass)}
.closing-actions{display:flex;flex-wrap:wrap;gap:var(--s2)}
@media(max-width:560px){.top-link{padding:6px 6px;font-size:13px}}
/* On a phone three columns do not fit, so each row becomes a small card: the
   topic, then our line, then theirs, each labelled. The other column's name
   comes in per language through --other on the table. */
@media(max-width:640px){
  .compare{min-width:0}
  .compare thead{display:none}
  .compare,.compare tbody,.compare tr,.compare th,.compare td{display:block;width:auto}
  .compare tr{padding:var(--s3) 0;border-bottom:1px solid var(--hair)}
  .compare th,.compare td,.compare tbody th{border:0;padding:4px 0;width:auto}
  .compare td{padding-left:12px}
  .compare td::before{display:block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;
    font-weight:600;color:var(--ink-3);margin-bottom:2px}
  .compare td.us::before{content:'Stemply';color:var(--brass)}
  .compare td:not(.us)::before{content:var(--other)}
}

/* The number is the message, so it gets the weight and everything else steps
   back: a brass rule on top, the figure, then a checklist, then the small
   print behind a hairline instead of another grey paragraph. */
.price-card{position:relative;overflow:hidden;
  border:1px solid var(--hair-hard);border-top:2px solid var(--brass);
  border-radius:var(--r-card);background:rgba(201,169,106,.05);
  padding:var(--s5);display:flex;flex-direction:column;gap:var(--s4);max-width:460px}
/* Two tiers side by side: the price a single salon pays, and the one that
   depends on how many counters there are. The second card wears no brass rule
   and no figure — for a chain the number is a conversation, and pretending
   otherwise would invite the wrong ones. */
.price-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s5);align-items:stretch}
.price-grid .price-card{max-width:none}
/* The small print lines up along the bottom whatever the lists weigh. */
.price-grid .price-card .fine{margin-top:auto}
.price-quote{border-top-color:var(--hair-hard);background:rgba(255,255,255,.022)}
.price-quote .price-note{
  border-color:var(--hair-hard);background:rgba(255,255,255,.04);color:var(--ink-2);
}
.price-card.price-quote .price b{
  font-family:inherit;font-size:30px;font-weight:600;color:var(--ink);letter-spacing:-.01em;
}
/* Pro is the one to look at: a full brass frame and a little lift, the badge
   filled instead of outlined. Standard stays the quiet default next to it. */
.price-pro{border:1px solid rgba(201,169,106,.55);border-top:2px solid var(--brass);
  background:rgba(201,169,106,.09);box-shadow:0 18px 50px -28px rgba(201,169,106,.55)}
.price-pro .price-note{background:var(--brass);border-color:var(--brass);color:#1a1408}
.price-lead{margin:0;color:var(--ink);font-size:14.5px;font-weight:600}
@media(max-width:1100px){.price-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .price-grid .price-quote{grid-column:1/-1}}
@media(max-width:860px){.price-grid{grid-template-columns:1fr}}
.price-note{align-self:flex-start;padding:4px 11px;border-radius:999px;
  border:1px solid rgba(201,169,106,.35);background:rgba(201,169,106,.10);
  font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--brass)}
.ticks{list-style:none;padding:0}
.ticks li{position:relative;padding-left:26px}
.ticks li::before{content:'';position:absolute;left:4px;top:.55em;width:9px;height:5px;
  border-left:2px solid var(--brass);border-bottom:2px solid var(--brass);
  transform:rotate(-45deg)}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .price-card{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}
}
.price-card .price{display:flex;align-items:baseline;gap:10px;margin:0}
.price-card .price b{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:56px;
  font-weight:500;color:var(--brass);line-height:.95;letter-spacing:-.02em}
.price-card .price span{color:var(--ink-2);font-size:14px}
.price-card .fine{padding-top:var(--s4);border-top:1px solid var(--hair);margin:0}
.price-card ul{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:7px;
  color:var(--ink-2);font-size:14.5px}
.fine{font-size:13px;color:var(--ink-3);max-width:60ch}

.legal{max-width:70ch;margin-inline:auto;padding:var(--s6) 0;display:flex;flex-direction:column;gap:var(--s3)}
.legal h1{margin:0;font-size:32px}
.legal h2{margin:var(--s4) 0 0;font-size:18px}
.legal p,.legal li{color:var(--ink-2);font-size:15px}
.legal p{margin:0}
.legal ul{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:6px}
.legal .updated{font-size:13px;color:var(--ink-3)}
.seller{display:grid;grid-template-columns:auto 1fr;gap:6px var(--s4);margin:var(--s3) 0 0;
  padding:var(--s4);border:1px solid var(--hair);border-radius:var(--r-control);background:var(--well);
  font-size:14px}
.seller dt{color:var(--ink-3)}
.seller dd{margin:0;color:var(--ink)}

.public-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--s4);padding:var(--s5) 0 0;border-top:1px solid var(--hair);
  font-size:13px;color:var(--ink-3)}
.foot-legal{display:flex;flex-wrap:wrap;gap:var(--s4)}
.foot-legal a{color:var(--ink-2)}
.foot-legal a:hover{color:var(--brass)}
/* Getting in touch is an action, so it looks like one. The two buttons sit at
   the end of the legal row rather than under it: on a phone the row wraps and
   only the copyright drops to a line of its own. */
.foot-reach{display:flex;align-items:center;gap:var(--s2);margin-left:auto}
/* One of these is a button, so the shared button padding, height, shadow and
   fill all have to be undone or the circle stops being a circle. */
.reach{position:relative;display:grid;place-items:center;width:38px;height:38px;flex:0 0 auto;
  min-height:0;padding:0;background:transparent;box-shadow:none;
  border:1px solid var(--hair-hard);border-radius:999px;color:var(--ink-2);cursor:pointer;
  transition:border-color var(--t-state),color var(--t-state),background var(--t-state)}
.reach svg,.reach .icon{grid-area:1/1;width:17px;height:17px}
.reach:hover{border-color:var(--brass);color:var(--brass);background:var(--brass-wash)}

/* Copy feedback: the envelope swaps for a tick and a label rises above the
   button. Both icons share one grid cell so nothing shifts as they trade. */
.reach .i-check{opacity:0;transform:scale(.4) rotate(-12deg)}
.reach .icon,.reach .i-mail,.reach .i-check{transition:opacity .18s ease,transform .18s cubic-bezier(.2,.9,.3,1.4)}
.reach.copied{border-color:var(--good);color:var(--good);background:transparent}
.reach.copied .icon,.reach.copied .i-mail{opacity:0;transform:scale(.4)}
.reach.copied .i-check{opacity:1;transform:scale(1) rotate(0)}
.reach::after{
  content:attr(data-copied-label);
  position:absolute;bottom:calc(100% + 9px);left:50%;translate:-50% 0;
  padding:5px 10px;border-radius:8px;white-space:nowrap;
  background:var(--good);color:var(--void);
  font-size:11.5px;font-weight:600;letter-spacing:.04em;
  opacity:0;transform:translateY(5px) scale(.92);pointer-events:none;
  transition:opacity .18s ease,transform .18s cubic-bezier(.2,.9,.3,1.4);
}
.reach.copied::after{opacity:1;transform:translateY(0) scale(1)}
@media(prefers-reduced-motion:reduce){
  .reach .icon,.reach .i-mail,.reach .i-check,.reach::after{transition-duration:.001ms}
  .reach .i-check{transform:none}
}
.foot-mark{flex:0 0 auto}
@media(max-width:620px){
  .public-foot{gap:var(--s4);justify-content:flex-start;align-items:center}
  .foot-legal{gap:var(--s3) var(--s4);flex-basis:100%}
  .foot-reach{margin-left:0;gap:var(--s3)}
  .foot-mark{margin-left:auto}
}
@media(max-width:600px){
  .seller{grid-template-columns:1fr;gap:2px}
  .seller dd{margin-bottom:8px}
}

/* ---------- Channels: one row per way in ----------------------------------
   The QR is the row's face, because that is the thing that gets printed and
   stuck on a counter; the link under the name is what gets pasted into a bio.
   Everything an owner does with a channel -- copy it, take it to a printer,
   retire it -- sits on the right of the same row. */
.channel-list{list-style:none;padding:0;margin:var(--s4) 0 0}
.channel{
  display:grid;grid-template-columns:88px minmax(0,1fr) auto;
  align-items:center;gap:var(--s4);
  padding:var(--s4) 0;border-bottom:1px solid var(--hair-soft);
}
.channel:last-child{border-bottom:0}
.channel-qr{
  width:88px;height:88px;border-radius:var(--r-control);
  background:#fff;padding:5px;image-rendering:pixelated;
}
.channel-body{min-width:0;display:flex;flex-direction:column;gap:5px}
.channel-body strong{color:var(--ink);font-size:15px;font-weight:600}
.channel-link{
  font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12px;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.channel-tally{font-size:13px;color:var(--ink-2)}
.channel-tally b{font-family:'JetBrains Mono',ui-monospace,monospace;font-weight:500;color:var(--brass)}
.channel-note{font-size:12px;color:var(--ink-4)}
.channel .ratio-track{width:100%;max-width:280px}
.channel-actions{display:flex;align-items:center;gap:var(--s2)}
/* A download is a link, so it has to be told to look like the button it is. */
.pill-button{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:38px;padding:0 13px;border-radius:999px;
  border:1px solid var(--hair-hard);color:var(--ink-2);
  font-size:11px;font-weight:600;letter-spacing:.1em;
  transition:border-color var(--t-state),color var(--t-state),background var(--t-state);
}
.pill-button:hover{border-color:var(--brass);color:var(--brass);background:var(--brass-wash)}

/* ---------- Where the customers came from --------------------------------- */
.sources{display:flex;flex-direction:column;gap:var(--s3)}
.source{display:grid;grid-template-columns:minmax(90px,150px) minmax(0,1fr) 74px;align-items:center;gap:var(--s4)}
.source-name{font-size:13px;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.source-track{height:10px;border-radius:999px;background:rgba(255,255,255,.06);overflow:hidden}
.source-fill{
  display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,var(--brass-deep),var(--brass));
  transform-origin:left;animation:ratio-in var(--t-surface) both;
}
/* The residue is not a channel anyone chose, so it does not wear the brass. */
.source.direct .source-fill{background:rgba(255,255,255,.16)}
.source-count{
  text-align:right;font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:15px;color:var(--ink);
}
.source-count small{display:block;font-size:11px;color:var(--ink-4)}
@media(max-width:760px){
  .channel{grid-template-columns:72px minmax(0,1fr);gap:var(--s3)}
  .channel-qr{width:72px;height:72px}
  .channel-actions{grid-column:1 / -1;flex-wrap:wrap}
  .channel-actions .icon-button:last-child{margin-left:auto}
  .channel .ratio-track{max-width:none}
  .source{grid-template-columns:minmax(78px,1fr) 60px;gap:var(--s2) var(--s3)}
  .source-track{grid-column:1 / -1;order:3}
}

/* ---------- Scrollbars ---------------------------------------------------- */
/* Two independent sets on purpose. Engines disagree about which wins -- a
   browser that honours the standard properties ignores the -webkit- ones, and
   the other way round -- so each set has to produce the intended bar on its
   own rather than the two of them combining. Same colours in both, so it does
   not matter which one the browser picks.

   Inherited from :root, which is what puts the same bar on the page, the nav
   rail, wide tables and the chart strip without listing them. */
:root{scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent}

::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  /* The transparent border is padding: it keeps the visible thumb at 4px
     while the grab area stays the full 10px. */
  background:var(--scroll-thumb);
  background-clip:content-box;
  border:3px solid transparent;
  border-radius:999px;
}
::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hi);background-clip:content-box}
::-webkit-scrollbar-corner{background:transparent}
/* No stepper arrows: they are the least minimal part of a default bar. */
::-webkit-scrollbar-button{display:none;width:0;height:0}

/* Light surfaces. The metal card and the smoke follow the page. */
:root[data-theme=light]{
  color-scheme:light;
  --void:#F6F7F9;--chrome:#FFFFFF;--surface-hi:#FFFFFF;--surface-lo:#F9FAFC;--well:#F0F2F5;
  --ink:#171C23;--ink-2:#465160;--ink-3:#626C79;--ink-4:#737E8B;
  --brass:#85621F;--brass-hi:#6D4C12;--brass-dim:#947330;--brass-deep:#73531B;--brass-wash:#F3EAD6;--on-brass:#FFFFFF;
  --danger:#A73530;--danger-deep:#8C2925;--danger-wash:#FFF0ED;--good:#287249;
  --hair:rgba(24,32,44,.10);--hair-soft:rgba(24,32,44,.06);--hair-hard:rgba(24,32,44,.20);
  --e1:inset 0 1px 0 rgba(255,255,255,.9);
  --e2:inset 0 1px 0 #fff,0 14px 36px -24px rgba(32,41,56,.22);
  --e3:inset 0 1px 0 #fff,0 24px 64px -24px rgba(32,41,56,.24);
}
[data-theme=light]{--scroll-thumb:rgba(90,64,15,.30);--scroll-thumb-hi:rgba(90,64,15,.52)}
[data-theme=light] .rail,[data-theme=light] .topbar,[data-theme=light] .cashier-actions{background:rgba(255,255,255,.92)}
[data-theme=light] .language-options,[data-theme=light] #toast{background:rgba(255,255,255,.98)}
[data-theme=light] input:hover,[data-theme=light] select:hover,[data-theme=light] textarea:hover{border-color:#A9AFB8}
[data-theme=light] input:focus,[data-theme=light] select:focus,[data-theme=light] textarea:focus{background:#fff}
[data-theme=light] button.primary:hover,[data-theme=light] .button.primary:hover{background:linear-gradient(180deg,#947330,#73531B)}
[data-theme=light] button.destructive,[data-theme=light] .button.destructive{color:#fff}
[data-theme=light] .form-error,[data-theme=light] #toast.error{color:#922F2A}
[data-theme=light] .rail-link.selected,[data-theme=light] .rail-link:hover,[data-theme=light] .language-options a:hover,
[data-theme=light] .language-picker summary:hover,[data-theme=light] .language-picker[open] summary,
[data-theme=light] button.ghost:hover,[data-theme=light] .button.ghost:hover,[data-theme=light] .icon-button:hover,
[data-theme=light] tbody tr:hover,[data-theme=light] .disclosure>summary:hover{background:rgba(24,32,44,.05)}
[data-theme=light] .ratio-track{background:rgba(24,32,44,.10)}
/* A dark slab on a white page was the loudest thing on screen, so the card
   becomes pale champagne metal and inherits the page's own ink and brass. */
[data-theme=light] .hero-card{
  border-color:rgba(133,98,31,.24);
  background:linear-gradient(145deg,#FFFFFF 0%,#F5F2EB 35%,#EFE4CE 65%,#FAF9F6 100%);
  box-shadow:
    0 24px 48px -24px rgba(24,32,44,.28),
    0 6px 18px -12px rgba(24,32,44,.16),
    inset 0 1px 0 #fff;
}
/* Screen blending is a no-op against near-white, so the holo sweep tints the
   metal instead of glowing on it; the specular highlight keeps screen. */
[data-theme=light] .card-holo{
  mix-blend-mode:multiply;
  background:linear-gradient(
    var(--holo-angle,135deg),
    transparent 0%,
    rgba(133,98,31,.04) 25%,
    rgba(133,98,31,.11) 40%,
    rgba(133,98,31,.07) 50%,
    rgba(133,98,31,.04) 60%,
    transparent 80%);
}
[data-theme=light] .card-shine{
  background:radial-gradient(
    circle at var(--shine-x,50%) var(--shine-y,-20%),
    rgba(255,255,255,.85) 0%,
    rgba(255,255,255,.35) 20%,
    transparent 50%);
}
[data-theme=light] .hero-tag{border-color:rgba(133,98,31,.30);background:rgba(133,98,31,.07)}
/* The engraving is baked gold; pale gold on cream is invisible, so darken it. */
[data-theme=light] .hero-engraving img{filter:brightness(.6) saturate(1.3)}
@media(max-width:760px){
  /* The rule above is unmedia'd and would otherwise replace the phone sweep. */
  [data-theme=light] .card-shine{
    background:linear-gradient(105deg,
      transparent 0%,transparent 35%,
      rgba(255,255,255,.45) 45%,
      rgba(255,255,255,.85) 50%,
      rgba(255,255,255,.45) 55%,
      transparent 65%,transparent 100%) 0 0/200% 100%;
  }
}
/* No plate at all on the light theme: the smoke itself is the button. That
   only works because the light palette is compressed into a mid-brass band
   (see PALETTES in app.js) instead of the wide near-white range it had.
   The ring is what draws the button's edge now that no slab does, and the
   shadow carries the type over the brightest wisps without putting a visible
   slab back. */
[data-theme=light] .smoky.on{box-shadow:inset 0 0 0 1px rgba(90,64,15,.55)}
[data-theme=light] .smoky.on .smoky-face,
[data-theme=light] .smoky.on:hover .smoky-face{
  background:transparent;color:#171C23;text-shadow:0 1px 2px rgba(255,248,230,.55);
}

/* Worn by the root only while the toggle switches, never at rest: a standing
   transition on every element would also slow hovers and the first paint.
   The card's two gradients share an angle and stop positions, so they really
   do interpolate rather than snap.

   This deliberately outranks the reduced-motion block above (a class beats
   `*` even between two !important rules). Nothing moves here, it is a colour
   cross-fade that removes a flash instead of adding motion -- the same call
   already made for the smoke. */
.theme-shifting,.theme-shifting *,.theme-shifting *::before,.theme-shifting *::after{
  transition:
    background-color .38s ease,background-image .38s ease,color .38s ease,
    border-color .38s ease,box-shadow .38s ease,fill .38s ease,filter .38s ease!important;
}
/* The rule above replaces the whole transition list, which would drop the
   `left` that slides the knob -- on the very control being clicked. */
.theme-shifting .theme-control .slider{transition:background .4s!important}
.theme-shifting .theme-control .slider::before{transition:left .4s,background .4s,box-shadow .4s!important}

/* The landing gets the same two light sources, placed for its own layout:
   warm behind the card on the left, cool low on the right. */
body:has(.public-main)::before{
  background:
    radial-gradient(46vw 44vh at 26% 22%,rgba(201,169,106,.20),transparent 64%),
    radial-gradient(44vw 46vh at 82% 58%,rgba(110,140,200,.13),transparent 66%);
}
[data-theme=light] body:has(.public-main)::before{
  background:
    radial-gradient(46vw 44vh at 26% 22%,rgba(191,150,64,.26),transparent 64%),
    radial-gradient(44vw 46vh at 82% 58%,rgba(96,132,208,.18),transparent 66%);
}
[data-theme=light] body:has(.auth-main)::before{
  background:
    radial-gradient(calc(48 * var(--vw)) calc(52 * var(--vh)) at 70% 50%,rgba(191,150,64,.34),transparent 64%),
    radial-gradient(calc(44 * var(--vw)) calc(48 * var(--vh)) at 14% 74%,rgba(96,132,208,.24),transparent 64%),
    radial-gradient(calc(36 * var(--vw)) calc(40 * var(--vh)) at 30% 10%,rgba(201,169,106,.20),transparent 62%);
}
@media(max-width:1350px){
  [data-theme=light] body:has(.auth-main)::before{
    background:
      radial-gradient(calc(90 * var(--vw)) calc(60 * var(--vh)) at 50% 70%,rgba(191,150,64,.28),transparent 65%),
      radial-gradient(calc(80 * var(--vw)) calc(46 * var(--vh)) at 20% 14%,rgba(96,132,208,.20),transparent 62%);
  }
}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  [data-theme=light] .auth-panel{
    border-top-color:rgba(255,255,255,.95);background:rgba(255,255,255,.45);
  }
}

/* Sun/moon switch adapted from Uiverse.io by satyamchaudharydev. */
.theme-control{display:flex;align-items:center;flex-shrink:0;min-height:44px}
.theme-control .switch{
  --width-of-switch:3.5em;--height-of-switch:2em;--size-of-icon:1.4em;--slider-offset:.3em;
  display:block;position:relative;width:var(--width-of-switch);height:44px;
  margin:0;font-size:16px;letter-spacing:0;text-transform:none;
}
.theme-control .switch input{
  position:absolute;inset:0;opacity:0;width:100%;height:100%;min-width:0;min-height:0;
  margin:0;padding:0;border:0;cursor:pointer;z-index:2;
}
.theme-control .slider{
  position:absolute;top:6px;bottom:6px;left:0;right:0;background:#E9E5DB;
  border-radius:30px;box-shadow:inset 0 0 0 1px rgba(124,97,44,.2);transition:background .4s;
}
.theme-control .slider::before{
  position:absolute;content:"";height:var(--size-of-icon);width:var(--size-of-icon);
  border-radius:20px;left:var(--slider-offset);top:50%;transform:translateY(-50%);
  background:linear-gradient(40deg,#B07E24,#E7C57E 70%);transition:left .4s,background .4s,box-shadow .4s;
}
.theme-control input:checked + .slider{background:#292C32}
.theme-control input:checked + .slider::before{
  left:calc(100% - (var(--size-of-icon) + var(--slider-offset)));background:#292C32;
  box-shadow:inset -3px -2px 5px -2px #C9A96A,inset -10px -4px 0 0 #E5D2A9;
}
.theme-control input:focus-visible + .slider{outline:2px solid var(--brass);outline-offset:3px}
.theme-fallback{display:grid;place-items:center;width:56px;height:44px;color:var(--brass);font-size:24px;border-radius:var(--r-control)}
.theme-fallback:hover{background:var(--brass-wash)}
@media(min-width:1351px){.rail-actions{flex-wrap:wrap}.rail-actions .logout-form{flex-basis:100%}}

/* ---------- The dashboard on a phone --------------------------------------
   A rail built for a 248px column does not survive being folded into a strip
   of unlabelled icons at the top of a 375px screen: seven of them scroll out
   of reach, and the right-hand end of every row -- the delete button, the last
   visit -- falls off the edge. So below 760px the shell is rebuilt rather than
   squeezed. Navigation moves to a fixed bar under the thumb, tables become
   cards, and every row wraps instead of overflowing.
   Placed last so it answers the earlier max-width blocks. */
@media(max-width:760px){
  .rail{
    position:fixed;left:0;right:0;bottom:0;top:auto;z-index:60;
    height:auto;min-height:0;align-self:stretch;
    flex-direction:row;align-items:stretch;gap:0;
    padding:6px 6px calc(6px + env(safe-area-inset-bottom));
    border-right:0;border-bottom:0;border-top:1px solid var(--hair-hard);
    background:rgba(11,12,14,.88);
  }
  [data-theme=light] .rail{background:rgba(246,247,249,.9)}
  .rail .brand,.rail .plan-badge{display:none}
  .rail-nav{flex:1;flex-direction:row;gap:2px;overflow:visible;min-width:0}
  .rail-link{
    flex:1 1 0;min-width:0;min-height:52px;padding:7px 2px;gap:4px;
    flex-direction:column;justify-content:center;border-radius:14px;
    font-size:10px;font-weight:600;letter-spacing:.01em;text-align:center;
  }
  .rail-link span{
    display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .rail-link.selected{background:var(--brass-wash);box-shadow:none}
  .rail-nav .rail-link{position:relative}
  .rail-nav .rail-link .pro-tag{
    position:absolute;top:4px;left:calc(50% + 7px);margin:0;padding:0 3px;
    font-size:7.5px;line-height:12px;letter-spacing:.04em;border-radius:4px;max-width:none;
  }
  .rail-more:not([hidden]){
    display:flex;flex:0 0 58px;flex-direction:column;align-items:center;justify-content:center;
    gap:4px;min-height:52px;padding:7px 2px;margin:0;border:0;border-radius:14px;
    background:transparent;box-shadow:none;color:var(--ink-3);
    font-size:10px;font-weight:600;letter-spacing:.01em;text-transform:none;
  }
  .rail-more .icon{color:var(--ink-4)}
  .rail-more[aria-expanded=true]{color:var(--ink);background:var(--brass-wash)}
  .rail-more[aria-expanded=true] .icon{color:var(--brass)}

  /* The sheet. display:none rather than a faded-out layer, so its links stay
     out of the tab order and the panel cannot be tapped through. The rise is
     an animation, not a transition: the open state is upright on its own, so
     a browser that never runs the animation still shows an upright sheet. */
  .rail-rest{display:none}
  .rail-rest[data-open]{
    display:flex;flex-direction:column;gap:var(--s3);
    position:fixed;top:auto;right:8px;bottom:calc(66px + env(safe-area-inset-bottom));left:auto;
    width:min(280px,calc(100vw - 16px));
    padding:var(--s4);border:1px solid var(--hair-hard);border-radius:18px;
    background:var(--chrome);box-shadow:0 26px 60px rgba(0,0,0,.55);
    animation:sheet-in var(--t-surface) ease-out;
  }
  @keyframes sheet-in{from{opacity:0;transform:translateY(10px)}}
  .rail-nav-rest{flex:0 0 auto;flex-direction:column;gap:2px}
  .rail-nav-rest .rail-link{
    flex:0 0 auto;flex-direction:row;justify-content:flex-start;text-align:left;
    min-height:44px;padding:0 var(--s3);border-radius:var(--r-control);font-size:14px;font-weight:500;
  }
  .rail-foot{
    flex-direction:column;align-items:stretch;gap:var(--s3);
    margin:0;padding-top:var(--s3);padding-bottom:0;border-top:1px solid var(--hair);
    position:static;background:transparent;
  }
  .rail-tenant{display:flex}
  .rail-actions{justify-content:space-between}
  .rail-actions .logout-form>button span{display:inline}
  .rail-actions .language-options{top:auto;bottom:calc(100% + var(--s2));right:0;left:auto}
  /* Clear the fixed bar so the last row of every page stays reachable. */
  footer{padding-bottom:calc(var(--s5) + 58px + env(safe-area-inset-bottom))}

  /* Heading: the business name, the screen and its one action, without
     spending a third of the screen saying so. */
  .container{padding-top:var(--s5)}
  h1{font-size:26px}
  .page-heading{margin-bottom:var(--s5);padding-bottom:var(--s4);gap:var(--s4)}
  .page-heading .eyebrow{margin-bottom:var(--s2)}
  .panel{padding:var(--s4)}
  .metric{padding:var(--s4)}
  .metric{min-width:0}
  .metric-value{font-size:30px;margin:var(--s3) 0 var(--s1)}
  .metric-date{font-size:21px}
  .metric-label{font-size:10px;letter-spacing:.12em}

  /* Thirty day-labels cannot share 335px, so the chart scrolls and each
     column is at least as wide as the date under it. */
  .chart{gap:8px;min-height:170px}
  .chart-column{min-width:40px}
  .chart-day{font-size:10px}

  /* A table is a desktop object. Each row becomes a card: the name on top,
     the figures labelled underneath, the action pinned to the corner. */
  .table-wrap{border:0;background:transparent;overflow:visible}
  .table-wrap table,.table-wrap tbody,.table-wrap tr,.table-wrap td{display:block;width:auto}
  .table-wrap thead{display:none}
  .table-wrap tr{
    position:relative;margin-bottom:var(--s3);padding:var(--s4);
    border:1px solid var(--hair);border-radius:var(--r-card);background:var(--well);
  }
  .table-wrap tr:last-child{margin-bottom:0}
  .table-wrap td{
    display:flex;align-items:baseline;justify-content:space-between;gap:var(--s4);
    padding:5px 0;border:0;
  }
  .table-wrap td[data-label]::before{
    content:attr(data-label);flex-shrink:0;
    font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);
  }
  .table-wrap td:first-child{
    display:block;margin-bottom:var(--s2);padding:0 46px var(--s3) 0;
    border-bottom:1px solid var(--hair-soft);
  }
  .table-wrap .row-actions{position:absolute;top:var(--s3);right:var(--s3);width:auto;padding:0}
  .table-wrap tr:has(.row-actions .icon-button+.icon-button) td:first-child{padding-right:96px}
  /* Four buttons (customers: book, edit, write, delete) leave the name no
     room beside them: they go to the foot of the card instead. */
  .table-wrap tr:has(.row-actions .icon-button+.icon-button+.icon-button+.icon-button) td:first-child{padding-right:0}
  .table-wrap tr:has(.row-actions .icon-button+.icon-button+.icon-button+.icon-button) .row-actions{
    position:static;display:flex;justify-content:flex-end;gap:2px;margin-top:var(--s2);padding-top:var(--s2);border-top:1px solid var(--hair-soft)}
  .table-wrap .num{text-align:right}

  /* Cashier rows: name and count on the first line, the PIN, the state and
     the two buttons on the second. ::after is the forced line break. */
  .entity-list li{flex-wrap:wrap;gap:var(--s2)}
  .entity-list .chip{padding:5px 9px;letter-spacing:.05em}
  .entity-list .pin-chip{gap:5px}
  .entity-list li::after{content:'';order:1;flex-basis:100%;height:0}
  .entity-list li>.chip,.entity-list li>.icon-button{order:2}
  .entity-list li>.icon-button:last-child{margin-left:auto}
  /* A name and one button: no second line to break onto. */
  .entity-list.plain li{flex-wrap:nowrap;gap:var(--s4)}
  .entity-list.plain li::after{content:none}
}

/* ---------- The opening screen ------------------------------------------
   Between the tap and the wallet there is a wait -- the pass is built and
   signed on demand, and the Google route calls Google before it redirects.
   This screen is that wait, made legible: it says whose card is opening, it
   moves while the server works, and it never asks which wallet the phone has,
   because the phone already answered that in its user agent. The link at the
   bottom is the way out if the redirect is blocked. */
body:has(.opening){display:flex;flex-direction:column;min-height:calc(100 * var(--svh))}
body:has(.opening) .topbar{flex-shrink:0}
.opening-main{flex:1;align-items:center}
.opening{
  display:flex;flex-direction:column;align-items:center;gap:var(--s4);
  text-align:center;max-width:340px;
  animation:opening-rise .5s cubic-bezier(.2,.8,.2,1);
}
@keyframes opening-rise{from{opacity:0;transform:translateY(14px)}}
.opening .eyebrow{margin:0}
.opening-chip{
  position:relative;display:grid;place-items:center;
  width:72px;height:72px;margin-top:var(--s2);border-radius:20px;
  border:1px solid rgba(201,169,106,.32);color:var(--brass);
  background:linear-gradient(145deg,var(--surface-hi),var(--surface-lo));
  box-shadow:0 14px 34px rgba(0,0,0,.5),0 0 44px -12px rgba(201,169,106,.5);
}
.opening-chip .icon{width:30px;height:30px}
/* The ring is the only thing on the screen that says "working". */
.opening-chip::after{
  content:'';position:absolute;inset:-7px;border-radius:26px;
  border:2px solid rgba(201,169,106,.34);animation:opening-ping 1.4s ease-out infinite;
}
@keyframes opening-ping{from{transform:scale(.9);opacity:.7}to{transform:scale(1.25);opacity:0}}
.opening-dots{display:flex;gap:7px}
.opening-dots i{
  width:8px;height:8px;border-radius:999px;background:var(--brass);opacity:.35;
  animation:opening-blink 1.2s infinite;
}
.opening-dots i:nth-child(2){animation-delay:.2s}
.opening-dots i:nth-child(3){animation-delay:.4s}
@keyframes opening-blink{0%,100%{opacity:.3;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}
.opening-msg{margin:0;font-size:16px;font-weight:600;color:var(--ink)}
.opening-hint{margin:0;font-size:13px;color:var(--ink-3)}
.opening-hint a{color:var(--brass);font-weight:600}
.opening .share-qr{width:170px;margin:var(--s2) 0 0}
.opening-add{min-width:240px;justify-content:center;margin-top:var(--s2)}
/* Nothing to open. The chip stops glowing rather than pretending to work. */
.opening-stalled .opening-chip{
  border-color:var(--hair-hard);color:var(--ink-3);box-shadow:none;
}
.opening:not([data-go]) .opening-dots,
.opening:not([data-go]) .opening-chip::after{display:none}
@media(prefers-reduced-motion:reduce){
  .opening-chip::after{display:none}
  .opening-dots i{animation:none;opacity:.6}
}

/* Stacked and short at the same time -- a small laptop, a phone in landscape.
   The room comes out of the panel's padding and the heading, never out of the
   field heights: those are the touch targets. */

/* The way out of the opening screen, once somebody has had to use it. */
@keyframes wallet-spin{to{rotate:1turn}}
.button.working,a.working{opacity:.9}
.button.working::before,a.working::before{
  content:'';display:inline-block;vertical-align:-2px;width:13px;height:13px;margin-right:7px;flex-shrink:0;
  border:2px solid currentColor;border-top-color:transparent;border-radius:999px;
  animation:wallet-spin .7s linear infinite;
}
@media(prefers-reduced-motion:reduce){
  .button.working::before,a.working::before{animation-duration:2.4s}
}

/* Moving between sections is a navigation, so the browser gets to cross-fade
   it rather than the page flashing white. Ignored where unsupported. */
@view-transition{navigation:auto}
@media(prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}

/* How to keep the till on the home screen: one quiet panel above the scanner. */
.install-hint{display:flex;flex-direction:column;gap:var(--s3);border-color:rgba(201,169,106,.35)}
.install-hint strong{color:var(--ink)}
.install-hint p{margin:4px 0 0;color:var(--ink-2);font-size:14px}
.install-hint .install-steps{margin:0;color:var(--ink);font-size:14px}
.install-hint .form-actions{margin:0}

/* Buttons under the card. The preview stands where an iPhone would hold the
   pass; the choices sit beside it as switches, each with the one field it needs. */
.actions-layout{display:grid;grid-template-columns:minmax(290px,350px) 1fr;gap:var(--s5);align-items:start}
.actions-preview{margin:0;display:flex;flex-direction:column;gap:var(--s3);padding:var(--s4);
  border-radius:var(--r-sheet);background:var(--well);border:1px solid var(--hair);position:sticky;top:var(--s4)}
.preview-pass{aspect-ratio:1.586;border-radius:12px;padding:12px 14px;display:flex;flex-direction:column;gap:8px;
  background:linear-gradient(150deg,#3a2c12,#16110a 70%);color:#F5EBD6;box-shadow:0 14px 30px -18px rgba(0,0,0,.8)}
.preview-pass strong{font-size:14px;font-weight:600;letter-spacing:.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.preview-logo{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:700;
  background:#C9A96A;color:#1A1405}
.preview-lines{margin-top:auto;display:flex;flex-direction:column;gap:6px}
.preview-lines i{display:block;height:6px;border-radius:3px;background:rgba(245,235,214,.22)}
.preview-lines i+i{width:55%}
.preview-tiles{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.preview-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:68px;
  padding:10px 6px;border-radius:12px;background:var(--surface-hi);border:1px solid var(--hair-hard);
  font-size:12.5px;font-weight:600;color:var(--ink);text-align:center;transition:opacity .2s,border-color .2s}
.preview-tile .tile-icon{display:grid;place-items:center;min-height:20px;color:var(--brass)}
.preview-tile .icon{width:20px;height:20px}
.preview-tile.is-empty{background:transparent;border-style:dashed;color:var(--ink-4);font-weight:500}
.preview-tile.is-missing{opacity:.5}
.actions-preview figcaption{font-size:12px;color:var(--ink-3);text-align:center}

.action-options{display:flex;flex-direction:column;gap:var(--s3)}
.action-option{border:1px solid var(--hair-hard);border-radius:var(--r-card);padding:var(--s3) var(--s4);
  background:linear-gradient(180deg,var(--surface-hi),var(--surface-lo));transition:border-color .2s,background .2s}
.action-option.is-on{border-color:rgba(201,169,106,.55);background:linear-gradient(180deg,var(--surface-hi),var(--brass-wash))}
.action-option.is-locked{opacity:.72}
.action-toggle{display:grid;grid-template-columns:40px 1fr auto auto;align-items:center;gap:var(--s3);margin:0;
  cursor:pointer;text-transform:none;letter-spacing:0;font-size:14.5px;font-weight:400;color:var(--ink);position:relative}
.action-toggle.static{grid-template-columns:40px 1fr;cursor:default}
.is-locked .action-toggle{cursor:not-allowed}
.action-toggle input[type=checkbox]{position:absolute;opacity:0;width:1px;height:1px;min-height:0;min-width:0;margin:0;pointer-events:none}
.action-icon{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;background:var(--well);color:var(--brass);
  border:1px solid var(--hair)}
.action-icon .icon{width:20px;height:20px}
.action-text strong{display:block;font-size:15px;font-weight:600;color:var(--ink)}
.action-text small{display:block;font-size:13px;color:var(--ink-3);margin-top:2px}
.action-state{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.action-state.ok{color:var(--good)}
.action-toggle .switch{width:40px;height:24px;border-radius:999px;background:var(--hair-hard);position:relative;transition:background .2s}
.action-toggle .switch::after{content:'';position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.35);transition:transform .2s}
.action-toggle input:checked~.switch{background:var(--brass)}
.action-toggle input:checked~.switch::after{transform:translateX(16px)}
.action-toggle input:focus-visible~.switch{outline:2px solid var(--brass);outline-offset:2px}
.action-toggle input:disabled:not(:checked)~.switch{opacity:.45}
.action-field{margin-top:var(--s3);padding-left:52px;display:flex;flex-direction:column;gap:6px}
.action-field input{width:100%}
.action-field small{font-size:12.5px}
.action-field .pro-note{margin:0}
.review-block{margin-top:var(--s5);padding-top:var(--s4);border-top:1px solid var(--hair);display:flex;flex-direction:column;gap:var(--s2)}
.review-block input{width:100%}
.card-actions .form-actions{margin-top:var(--s4)}
@media(max-width:860px){
  .actions-layout{grid-template-columns:1fr}
  .actions-preview{position:static;max-width:320px;width:100%;margin-inline:auto}
}
@media(max-width:640px){
  .action-toggle{grid-template-columns:40px 1fr auto}
  .action-state{grid-column:2;grid-row:2;justify-self:start}
  .action-toggle .switch{grid-column:3;grid-row:1}
  .action-field{padding-left:0}
}

/* A date field on iOS keeps its own width and pushes past the panel unless
   it is told to behave like any other input. */
input[type=date]{-webkit-appearance:none;appearance:none;display:block;min-width:0;max-width:100%}
input[type=date]::-webkit-date-and-time-value{text-align:left;margin:0}

/* What the join form asks: one row per field, asked on the left, required on
   the right, the second only live when the first is ticked. */
.join-fields{display:flex;flex-direction:column;gap:6px}
.join-field-row{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:8px 12px;border:1px solid var(--hair);border-radius:var(--r-control);background:var(--well)}
.join-field-row label.check{margin:0}
.pill-toggle{display:inline-flex;margin:0;cursor:pointer;text-transform:none;letter-spacing:0;font-weight:600}
.pill-toggle input{position:absolute;opacity:0;width:1px;height:1px;min-height:0;min-width:0;pointer-events:none}
.pill-toggle span{padding:5px 12px;border-radius:999px;border:1px solid var(--hair-hard);font-size:12.5px;color:var(--ink-3);
  transition:background .2s,color .2s,border-color .2s}
.pill-toggle input:checked+span{background:var(--brass);border-color:var(--brass);color:var(--on-brass)}
.pill-toggle input:focus-visible+span{outline:2px solid var(--brass);outline-offset:2px}
.pill-toggle input:disabled+span{opacity:.35;cursor:not-allowed}

/* Customers: who to show and in what order, above the table. */
.filter-bar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s3);margin-bottom:var(--s4)}
.filter-chips{display:flex;flex-wrap:wrap;gap:6px}
.filter-chip{display:inline-flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;font-size:13px;font-weight:500;
  border:1px solid var(--hair-hard);color:var(--ink-2);text-decoration:none;transition:background .2s,border-color .2s,color .2s}
.filter-chip b{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12px;font-weight:500;color:var(--ink-3)}
.filter-chip:hover{border-color:var(--brass-dim);color:var(--ink)}
.filter-chip.selected{background:var(--brass);border-color:var(--brass);color:var(--on-brass)}
.filter-chip.selected b{color:var(--on-brass)}
.sort-form{display:flex;align-items:center;gap:var(--s2)}
.sort-form label{margin:0;white-space:nowrap}
.sort-form select{width:auto;min-height:38px;padding:7px 12px}
.abo-cell{font-family:'JetBrains Mono',ui-monospace,monospace}
.abo-cell.is-low{color:var(--brass)}
.row-actions .icon-button{vertical-align:middle}
.row-actions .icon-button+.icon-button{margin-left:2px}

/* A customer's package: what is left at a glance, the corrections folded away. */
.package-summary{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s4)}
.package-big{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:44px;font-weight:500;color:var(--brass);line-height:1;white-space:nowrap}
.package-big small{font-size:20px;color:var(--ink-3);margin-left:4px}
.package-summary b{display:block;color:var(--ink);font-size:15px}
.package-summary small{display:block;color:var(--ink-3);font-size:13px;margin-top:2px}
.package-meter{display:block;height:6px;border-radius:3px;background:var(--hair-hard);margin-top:10px;overflow:hidden}
.package-meter span{display:block;height:100%;background:var(--brass);border-radius:3px}
.package-edit-box{border-top:1px solid var(--hair);padding-top:var(--s3);margin-bottom:var(--s4)}
.package-edit-box summary{display:inline-flex;align-items:center;gap:8px;cursor:pointer;color:var(--ink-2);font-size:14px;font-weight:500;list-style:none}
.package-edit-box summary::-webkit-details-marker{display:none}
.package-edit-box summary:hover{color:var(--ink)}
.package-edit{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 var(--s4);margin-top:var(--s4)}
.package-edit .field:first-child{grid-column:1/-1}
.package-edit-actions{grid-column:1/-1;display:flex;justify-content:space-between;gap:var(--s3)}
.danger-text{color:var(--danger)!important}
.package-give{border-top:1px solid var(--hair);padding-top:var(--s4)}
.package-give .inline-form{display:flex;gap:var(--s2)}
.package-give select{flex:1}
@media(max-width:640px){.package-edit{grid-template-columns:1fr}.package-big{font-size:36px}.package-give .inline-form{flex-direction:column}}

/* Messages: everyone or one customer, picked by typing. */
.segmented{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;margin-bottom:var(--s4);
  border-radius:calc(var(--r-control) + 4px);background:var(--well);border:1px solid var(--hair)}
.segmented label{margin:0;cursor:pointer;text-transform:none;letter-spacing:0}
.segmented input{position:absolute;opacity:0;width:1px;height:1px;min-height:0;min-width:0;pointer-events:none}
.segmented label>span{display:flex;align-items:center;justify-content:center;gap:8px;padding:9px 10px;border-radius:var(--r-control);
  font-size:14px;font-weight:600;color:var(--ink-2);transition:background .2s,color .2s}
.segmented .icon{width:17px;height:17px}
.segmented input:checked+span{background:var(--surface-hi);color:var(--ink);box-shadow:0 1px 0 rgba(255,255,255,.05),0 4px 14px -6px rgba(0,0,0,.6)}
.segmented input:focus-visible+span{outline:2px solid var(--brass);outline-offset:1px}
.segmented input:disabled+span{opacity:.5;cursor:not-allowed}
.recipient-picker{margin-bottom:var(--s4)}
.picker-search{position:relative}
.picker-results{list-style:none;margin:6px 0 0;padding:4px;border:1px solid var(--hair-hard);border-radius:var(--r-control);
  background:var(--surface-hi);max-height:280px;overflow:auto}
.picker-results button{width:100%;display:flex;align-items:center;gap:var(--s3);padding:8px 10px;border:0;border-radius:6px;
  background:transparent;color:var(--ink);text-align:left;cursor:pointer;min-height:0}
.picker-results button:hover,.picker-results button:focus-visible,.picker-results button.active{background:var(--brass-wash);outline:none}
.picker-results small,.picker-chosen small{display:block;color:var(--ink-3);font-size:12.5px}
.picker-results .avatar,.picker-chosen .avatar{flex:none}
.picker-chosen{display:flex;align-items:center;gap:var(--s3);padding:10px 12px;border:1px solid rgba(201,169,106,.45);
  border-radius:var(--r-control);background:var(--brass-wash)}
.picker-chosen b{color:var(--ink)}
.picker-empty{margin:8px 0 0}

.activity-list small .icon{display:inline-block;width:13px;height:13px;vertical-align:-2px;margin-right:4px}

/* Phones: the customers' search takes its own row, the export the next; the
   order select fills the row under the filters instead of running off it. */
@media(max-width:640px){
  .page-heading .head-actions{flex-wrap:wrap}
  .page-heading .head-actions>form.head-actions{flex:1 1 100%;min-width:0}
  .page-heading .head-actions>form.head-actions input{flex:1;min-width:0;width:auto}
  .page-heading .head-actions>form.head-actions button{flex:none}
  .page-heading .head-actions>.button{flex:1 1 100%}
  .sort-form{flex:1 1 100%;min-width:0}
  .sort-form select{flex:1;min-width:0;width:100%}
}

/* How much of a message limit is used, beside the panel title. */
.limit-meter{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.limit-meter.is-full{color:var(--brass)}
.notice-inline{margin:0 0 var(--s4);padding:10px 12px;border-radius:var(--r-control);font-size:13.5px;
  color:var(--ink-2);background:var(--brass-wash);border:1px solid rgba(201,169,106,.35)}

/* The assistant: a conversation on the left, the week's report beside it. */
.assistant-layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,340px);gap:var(--s5);align-items:start}
/* The conversation fills the screen below the heading (script sets the
   height); only the messages scroll, the question box stays in view. */
.assistant-chat{display:flex;flex-direction:column;min-height:420px}
.assistant-chat>.panel-head,.assistant-chat>.pro-note,.assistant-chat>.notice-inline,
.assistant-chat>.assistant-form,.assistant-chat>.assistant-note{flex:none}
.assistant-form{margin-top:var(--s3)}
.assistant-report{overflow:auto}
.report-switch .action-toggle{grid-template-columns:40px 1fr auto}
.report-head{display:flex;justify-content:space-between;align-items:center;margin:var(--s4) 0 var(--s2);padding-top:var(--s3);
  border-top:1px solid var(--hair);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.report-empty{margin:var(--s4) 0 0;padding-top:var(--s3);border-top:1px solid var(--hair);font-size:13.5px}
.assistant-chat .panel-head h3,.assistant-report .panel-head h3{display:flex;align-items:center;gap:8px}
.assistant-chat .panel-head h3 .icon{color:var(--brass)}
.assistant-log{display:flex;flex-direction:column;gap:var(--s3);flex:1;min-height:160px;overflow-y:auto;overflow-x:hidden;
  padding:var(--s2) 2px var(--s3);scroll-behavior:smooth}
.assistant-msg{display:flex;gap:10px;align-items:flex-start}
.assistant-msg.from-user{justify-content:flex-end}
.assistant-avatar{flex:none;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  background:var(--brass-wash);border:1px solid rgba(201,169,106,.4);color:var(--brass)}
.assistant-avatar .icon{width:16px;height:16px}
.assistant-bubble{max-width:min(560px,85%);padding:10px 14px;border-radius:14px;font-size:14.5px;line-height:1.55;
  background:var(--well);border:1px solid var(--hair);color:var(--ink)}
.from-user .assistant-bubble{background:linear-gradient(180deg,var(--brass-hi),var(--brass));border-color:var(--brass-deep);color:var(--on-brass)}
.assistant-bubble p{margin:0}
.assistant-bubble p+p,.assistant-bubble p+ul,.assistant-bubble ul+p{margin-top:8px}
.assistant-bubble ul,.assistant-text ul{margin:6px 0 0;padding-left:18px;display:flex;flex-direction:column;gap:4px}
.assistant-bubble.is-error{border-color:rgba(228,115,107,.4);color:var(--danger)}
.assistant-thinking{display:inline-flex;gap:4px;align-items:center;color:var(--ink-3)}
.assistant-thinking i{width:6px;height:6px;border-radius:50%;background:var(--brass);animation:assistant-dot 1.2s infinite ease-in-out}
.assistant-thinking i:nth-child(2){animation-delay:.15s}.assistant-thinking i:nth-child(3){animation-delay:.3s}
@keyframes assistant-dot{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}
@media(prefers-reduced-motion:reduce){.assistant-thinking i{animation:none;opacity:.7}}
.assistant-draft{margin-top:10px;padding:10px 12px;border-radius:10px;border:1px dashed rgba(201,169,106,.55);background:var(--brass-wash)}
.assistant-draft small{display:block;font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--brass)}
.assistant-draft p{margin:6px 0 8px;color:var(--ink)}
.assistant-suggestions{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(220px,100%),1fr));gap:8px;margin:2px 0 0 40px;min-width:0}
.assistant-suggestions .suggestion{display:flex;align-items:center;justify-content:flex-start;gap:10px;min-height:0;
  padding:11px 14px;border-radius:12px;text-align:left;font-size:14px;font-weight:500;line-height:1.35;
  color:var(--ink);background:var(--surface-hi);border:1px solid var(--hair-hard);box-shadow:none;cursor:pointer;
  min-width:0;white-space:normal}
.assistant-suggestions .suggestion .icon{flex:none;width:15px;height:15px;color:var(--brass)}
.assistant-suggestions .suggestion:hover{border-color:var(--brass-dim);background:var(--brass-wash)}
@media(max-width:640px){.assistant-suggestions{margin-left:0;grid-template-columns:1fr}}
.assistant-suggestions .filter-chip{cursor:pointer;background:transparent}
.assistant-form{display:flex;gap:var(--s2);align-items:flex-end}
.assistant-form textarea{flex:1;min-height:46px;max-height:180px;resize:none;line-height:1.45;padding:12px 14px}
.assistant-form button{flex:none;width:46px;min-width:46px;height:46px;padding:0}
.assistant-note{font-size:12.5px;margin:var(--s2) 0 0}
.assistant-text{font-size:14.5px;line-height:1.6;color:var(--ink-2)}
.assistant-text p{margin:0 0 8px}
.assistant-layout>*{min-width:0}
.assistant-chat .panel-head{flex-wrap:wrap;row-gap:6px}
@media(max-width:960px){.assistant-layout{grid-template-columns:1fr}}
@media(max-width:640px){.assistant-chat .limit-meter{white-space:normal}.assistant-bubble{max-width:100%}}
.rail-tenant-mark{overflow:hidden}
.rail-tenant-mark img{width:100%;height:100%;object-fit:cover;display:block}

/* How the customer sees the card: a switch between phones, one stage shown. */
.look-tabs{display:inline-flex;gap:4px;padding:4px;margin-bottom:var(--s4);border-radius:12px;background:var(--well);border:1px solid var(--hair)}
.look-tabs input{position:absolute;opacity:0;width:1px;height:1px;min-height:0;min-width:0;pointer-events:none}
.look-tabs label{margin:0;padding:8px 14px;border-radius:9px;cursor:pointer;text-transform:none;letter-spacing:0;font-size:13.5px;font-weight:600;color:var(--ink-2)}
.look-tabs input:checked+label{background:var(--surface-hi);color:var(--ink);box-shadow:0 4px 14px -6px rgba(0,0,0,.6)}
.look-tabs input:focus-visible+label{outline:2px solid var(--brass)}
.look-stage{display:none;justify-content:center}
.card-look:has(#look-poster:checked) [data-look=poster],
.card-look:has(#look-apple:checked) [data-look=apple],
.card-look:has(#look-google:checked) [data-look=google]{display:flex}
.look-note{text-align:center;font-size:12.5px;margin:var(--s3) 0 0}

/* The iOS 27 poster: the card's own picture with the phone's parts on top. */
.poster-phone{width:min(330px,100%);display:flex;flex-direction:column;gap:10px;padding:14px;border-radius:34px;background:#000}
.pass-poster{position:relative;aspect-ratio:458/642;border-radius:18px;overflow:hidden;background:#111}
.pass-poster .p-art{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* The logo picture is a 320x100 box with the mark contained in it; iOS
   gives the poster's logo about 35% of the card's width. */
.pass-poster .p-logo{position:absolute;left:6.5%;top:1.4%;width:37%;height:auto;object-fit:contain;object-position:left}
.pass-poster .p-name{height:auto;color:var(--card-fg);font-size:15px}
.pass-poster .p-code{position:absolute;left:50%;top:48%;transform:translateX(-50%);width:41%;aspect-ratio:1;padding:3%;background:#fff;border-radius:6px}
.pass-poster .p-code img{width:100%;height:100%;display:block;image-rendering:pixelated}
.pass-poster .p-strip{position:absolute;left:0;right:0;bottom:0;height:20%;display:flex;justify-content:space-between;align-items:center;
  padding:0 6.5%;background:linear-gradient(180deg,rgba(70,45,32,.55),rgba(52,33,24,.92));-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.pass-poster .p-strip span{display:flex;flex-direction:column;gap:2px;font-family:ui-monospace,'SF Mono','JetBrains Mono',monospace}
.pass-poster .p-strip .p-right{text-align:right}
.pass-poster .p-strip small{font-size:11px;color:var(--card-label)}
.pass-poster .p-strip b{font-size:15px;font-weight:500;color:var(--card-fg)}
.poster-phone .p-row{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:16px;background:#1c1c1e;color:#fff}
.poster-phone .p-info{flex-direction:column;align-items:flex-start;gap:2px}
.poster-phone .p-row small{display:block;font-size:12px;color:rgba(255,255,255,.55)}
.poster-phone .p-row b{display:block;font-size:14px;font-weight:600}
.poster-phone .p-icon{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:#ff3b30;color:#fff;flex:none}
.poster-phone .p-icon .icon{width:16px;height:16px}
.poster-phone .p-chev{color:rgba(255,255,255,.35);font-size:22px;line-height:1}
.card-look{padding:var(--s3)}
.card-look .look-tabs{display:flex;width:100%}
.card-look .look-tabs label{flex:1;text-align:center;padding:8px 6px;font-size:12.5px}
.card-look .poster-phone{width:100%}
.card-look .pass{max-width:100%}
.poster-phone .pass-poster{order:-2}
.poster-phone .p-info{order:-1}
.look-controls{display:flex;flex-direction:column;gap:10px;margin-top:var(--s3);padding:12px;border-radius:12px;background:var(--surface-hi);border:1px solid var(--hair)}
.look-range{display:flex;flex-direction:column;gap:8px;margin:0;text-transform:none;letter-spacing:0;font-size:13.5px;font-weight:500;color:var(--ink-2)}
.look-range b{color:var(--ink)}
.look-range input{width:100%;min-height:0;padding:0;border:0;background:transparent;accent-color:var(--brass)}
.look-controls label.check{margin:0;font-size:13.5px}


/* The older-iPhone card in proportion to its own width, measured off a real
   one (458px wide): every size is a share of the card, so the mock-up keeps
   the phone's look at any width instead of crowding on a narrow screen. */
.pass-apple{container-type:inline-size;padding:0}
/* The logo picture is a 320x100 box with the mark contained in it, so the
   box is drawn about twice the height the letters take on the phone. */
.pass-apple .a-head{padding:0.8cqw 3.6cqw 0;min-height:0}
.pass-apple .a-logo{height:17cqw;max-width:60%}
.pass-apple .a-name{font-size:3.6cqw}
.pass-apple .a-field small{font-size:2.8cqw}
.pass-apple .a-head-field b{font-size:3.5cqw}
.pass-apple .a-strip{width:100%;margin:0}
.pass-apple .a-fields{padding:2.6cqw 3.6cqw 0;gap:2.6cqw}
.pass-apple .a-fields .a-field b{font-size:5.6cqw}
.pass-apple .a-code{margin:auto auto 4.6cqw;padding:2.7cqw}
.pass-apple .a-code img{width:36cqw;height:36cqw}

/* ---------- Booking ---------------------------------------------------------
   The owner's day board, the setup screens, and the client's booking page and
   ticket. The board is drawn in minutes: --top and --len are minutes from the
   first hour shown, and --m is how tall a minute is. */
.nav-badge{margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:999px;display:inline-grid;place-items:center;
  background:var(--brass);color:var(--on-brass);font-size:11px;font-weight:700;line-height:1}
.field-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s3)}
.tag{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600;border:1px solid var(--hair-hard);color:var(--ink-2)}
.tag-on{border-color:color-mix(in srgb,var(--good) 50%,transparent);color:var(--good)}
.tag-muted{color:var(--ink-3)}

.day-nav{display:flex;align-items:center;gap:6px}
.day-nav .icon-button{font-size:22px;line-height:1;text-decoration:none}
.day-pick{display:contents}
.day-pick input{width:auto;min-width:150px}

.setup-steps{list-style:none;margin:var(--s4) 0 0;padding:0;display:grid;gap:var(--s2)}
.setup-steps li{display:flex;align-items:center;gap:var(--s3);color:var(--ink-2)}
.setup-steps li>span{flex:none;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;border:1px solid var(--hair-hard);font-weight:700;font-size:13px}
.setup-steps li.done{color:var(--ink)}
.setup-steps li.done>span{background:var(--brass-wash);border-color:var(--brass-dim);color:var(--brass)}
.setup-steps .icon{width:14px;height:14px}

.board-wrap{overflow-x:auto;margin:0 calc(-1 * var(--pad-card));padding:0 var(--pad-card) var(--s2)}
.board{--m:1.1px;display:flex;min-width:100%;gap:0}
.board-col{flex:1 0 170px;min-width:170px;border-left:1px solid var(--hair)}
.board-times{flex:0 0 52px;position:sticky;left:calc(-1 * var(--pad-card));z-index:3;background:var(--surface-hi)}
.board-head{height:40px;display:flex;align-items:center;justify-content:center;padding:0 var(--s2);font-weight:600;font-size:14px;
  border-bottom:1px solid var(--hair);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.board-track{position:relative;height:calc(var(--hours) * 60 * var(--m));
  background:repeating-linear-gradient(180deg,var(--hair) 0 1px,transparent 1px calc(60 * var(--m)))}
.board-times .board-track{background:none}
.board-times span{position:absolute;top:calc(var(--top) * var(--m));right:8px;transform:translateY(-50%);font-size:11px;color:var(--ink-3);
  font-family:'JetBrains Mono',ui-monospace,monospace}
.board-times span:first-child{transform:none}
.board-open,.board-off,.board-now{position:absolute;left:0;right:0;top:calc(var(--top) * var(--m))}
.board-open,.board-off{height:calc(var(--len) * var(--m))}
.board-open{background:color-mix(in srgb,var(--brass) 5%,transparent)}
.board-off{background:repeating-linear-gradient(135deg,var(--hair-soft) 0 6px,transparent 6px 12px)}
.board-now{height:2px;background:var(--danger);z-index:2}
.board-now::before{content:'';position:absolute;left:-4px;top:-3px;width:8px;height:8px;border-radius:50%;background:var(--danger)}
.board-item{position:absolute;left:4px;right:4px;top:calc(var(--top) * var(--m) + 1px);height:calc(var(--len) * var(--m) - 2px);min-height:22px;z-index:1;
  display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;gap:1px;padding:5px 8px;overflow:hidden;text-align:left;
  border:1px solid var(--hair-hard);border-left:3px solid var(--brass);border-radius:8px;background:var(--surface-hi);color:var(--ink);
  box-shadow:var(--e1);font:inherit;cursor:pointer;text-transform:none;letter-spacing:0}
.board-item:hover{border-color:var(--brass-dim)}
.board-line{display:flex;align-items:baseline;gap:6px;min-width:0;max-width:100%}
.board-item b{flex:none;font-size:12px;font-family:'JetBrains Mono',ui-monospace,monospace;color:var(--brass)}
.board-line span{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.board-item small{font-size:12px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.board-item.short{justify-content:center;padding:2px 8px}
.board-item.short small{display:none}
.board-item.status-arrived{border-left-color:var(--good)}
.board-item.status-arrived b{color:var(--good)}
.board-item.status-no_show{border-left-color:var(--danger);background:var(--danger-wash)}
.board-item.status-no_show b{color:var(--danger)}
.board-item.status-cancelled{opacity:.55;border-left-color:var(--ink-4);background:transparent;border-style:dashed;z-index:0}
.board-item.status-cancelled .board-line span{text-decoration:line-through}
.board-legend{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s4);margin:var(--s3) 0 0;padding:0;font-size:12.5px;color:var(--ink-3)}
.board-legend li{display:flex;align-items:center;gap:6px}
.board-legend li::before{content:'';width:10px;height:10px;border-radius:3px;background:var(--brass)}
.board-legend .status-arrived::before{background:var(--good)}
.board-legend .status-no_show::before{background:var(--danger)}
.board-legend .status-cancelled::before{background:transparent;border:1px dashed var(--ink-4)}

.booking-dialog{width:min(440px,calc(100vw - 32px));padding:var(--s5);border:1px solid var(--hair-hard);border-radius:var(--r-sheet);
  background:var(--surface-hi);color:var(--ink);box-shadow:var(--e3)}
.booking-dialog::backdrop{background:rgba(0,0,0,.55)}
.booking-dialog h2{margin:var(--s1) 0 var(--s3)}
.booking-facts{display:grid;gap:0;margin:0 0 var(--s4)}
.booking-facts>div{display:flex;justify-content:space-between;gap:var(--s4);padding:9px 0;border-bottom:1px solid var(--hair)}
.booking-facts>div:last-child{border-bottom:0}
.booking-facts dt{color:var(--ink-3);font-size:13.5px}
.booking-facts dd{margin:0;text-align:right;font-weight:600}
.booking-facts a{color:var(--brass)}
.booking-actions{display:flex;flex-wrap:wrap;gap:var(--s2)}
.booking-actions>*{flex:1 1 auto}
.booking-move{display:grid;gap:var(--s3);margin-top:var(--s4)}
.booking-move .form-actions{margin-top:0}

.owner-booking .client-pick{position:relative}
.owner-booking select[hidden],.owner-booking input[hidden]{display:none}

.hours-editor{display:grid;gap:6px;margin:var(--s3) 0}
.hours-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--hair-soft)}
.hours-row input[type="time"]{width:auto;min-width:96px;padding:6px 8px}
.hours-row .hours-day{flex:0 0 72px;font-weight:600}
.hours-row .hours-break{margin-left:var(--s2);color:var(--ink-3)}
.hours-break-times{display:inline-flex;align-items:center;gap:8px}
.hours-dash{color:var(--ink-3)}
.hours-row.off input[type="time"],.hours-row.off .hours-break{opacity:.35}

.entity-list .editable{display:block;padding:0}
.row-edit>summary{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) 0;cursor:pointer;list-style:none}
.row-edit>summary::-webkit-details-marker{display:none}
.row-edit[open]>summary .chev{transform:rotate(180deg)}
.row-edit>form{padding:0 0 var(--s4)}
.row-edit .grow strong,.row-edit .grow small{display:block}
.row-edit .grow small{margin-top:2px;color:var(--ink-3);font-size:13px;line-height:1.45}
.disclosure.inner{margin-top:var(--s3);border-top:1px solid var(--hair);padding-top:var(--s2)}
.checks{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);border:0;padding:0;margin:var(--s2) 0}
.checks legend{padding:0;margin-bottom:6px;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.checks small{flex-basis:100%}

.booking-link{display:flex;gap:var(--s4);align-items:flex-start;margin:var(--s4) 0;padding:var(--s4);border-radius:var(--r-card);
  border:1px solid var(--hair-hard);background:var(--well)}
.booking-link img{border-radius:8px;background:#fff;padding:6px;flex:none}
.booking-link a.mono{display:block;margin:4px 0;word-break:break-all;color:var(--brass)}
.booking-link .muted{margin:0 0 var(--s3)}
.mono{font-family:'JetBrains Mono',ui-monospace,monospace}
.calendar-feed code{display:block;padding:10px 12px;border-radius:var(--r-control);background:var(--well);border:1px solid var(--hair);
  font-size:12.5px;word-break:break-all;margin-bottom:var(--s3)}
.switch-row{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);margin:var(--s3) 0 var(--s4);
  text-transform:none;letter-spacing:0;font-size:15px;cursor:pointer}
.switch-row b{display:block;color:var(--ink)}
.switch-row small{display:block;color:var(--ink-3);font-size:13px;font-weight:500}
.switch-row .switch{position:relative;flex:none;width:46px;height:28px}
.switch-row .switch input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.switch-row .slider{position:absolute;inset:0;border-radius:999px;background:var(--hair-hard);transition:background var(--t-state)}
.switch-row .slider::before{content:'';position:absolute;left:3px;top:3px;width:22px;height:22px;border-radius:50%;background:#fff;
  transition:transform var(--t-state);box-shadow:0 1px 3px rgba(0,0,0,.3)}
.switch-row input:checked+.slider{background:var(--brass)}
.switch-row input:checked+.slider::before{transform:translateX(18px)}
.switch-row input:focus-visible+.slider{outline:2px solid var(--brass);outline-offset:2px}


.head-actions .button.square{flex:none;width:46px;padding:0;justify-content:center}
.head-actions .button.square .icon{margin:0}
@media(max-width:760px){
  .day-nav{width:100%}
  .day-pick input{flex:1;min-width:0;padding:0 10px;font-size:15px}
  .day-nav .button{flex:none;padding:0 12px}
  .page-heading .head-actions{flex-wrap:wrap}
  .board-col{flex-basis:150px;min-width:150px}
  .booking-link{flex-direction:column}
  .hours-row .hours-break{margin-left:0}
}
@media(max-width:420px){
  .field-row{grid-template-columns:1fr}
}
.notify-panel .notice{margin:0 0 var(--s3)}
/* Two ways to hear about bookings in one panel: this browser, and Telegram. */
.notify-way+.notify-way{margin-top:var(--s5);padding-top:var(--s5);border-top:1px solid var(--hair-soft)}
.notify-head{display:flex;align-items:flex-start;gap:var(--s4);margin-bottom:var(--s4)}
.notify-head .grow{min-width:0}
.notify-head strong{display:block;color:var(--ink);font-size:15px}
.notify-head small{display:block;margin-top:3px;font-size:13.5px;line-height:1.45;color:var(--ink-2)}
.notify-head .tag{flex:none}
.notify-chats{margin:0 0 var(--s3) 56px}
@media (max-width:640px){
  /* On a phone the note takes the full width under the icon, title and state. */
  .notify-head{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:'icon title tag' 'note note note';align-items:center;column-gap:var(--s3);row-gap:var(--s3)}
  .notify-head .avatar{grid-area:icon;width:36px;height:36px}
  .notify-head .grow{display:contents}
  .notify-head strong{grid-area:title}
  .notify-head small{grid-area:note;margin:0}
  .notify-head .tag{grid-area:tag}
  .notify-chats{margin-left:0}
}
.push-nudge a{white-space:nowrap}

/* Service photos: a square beside the service on the client's page, and the
   owner's upload tile under the service's form. */
.service-thumb{object-fit:cover;padding:0;border-radius:10px}
.photo-form{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;padding:0 0 var(--s4)}
.photo-drop{position:relative;display:flex;align-items:center;gap:var(--s3);padding:10px 14px 10px 10px;border-radius:var(--r-card);
  border:1px dashed var(--hair-hard);background:var(--well);cursor:pointer;text-transform:none;letter-spacing:0;font-size:14px;color:var(--ink);margin:0}
.photo-drop:hover{border-color:var(--brass-dim)}
.photo-drop img,.photo-plus{width:64px;height:64px;flex:none;border-radius:10px;object-fit:cover}
.photo-plus{display:grid;place-items:center;border:1px solid var(--hair);color:var(--brass)}
.photo-drop b{display:block}
.photo-drop small{display:block;color:var(--ink-3);font-size:12.5px;font-weight:500}
.photo-drop input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%}
.photo-drop.working{opacity:.6;pointer-events:none}
.currency-input{max-width:140px;text-transform:uppercase}
.linkish{display:inline-flex;align-items:center;gap:4px;padding:0;min-height:0;border:0;background:none;box-shadow:none;
  color:var(--brass);font:inherit;font-weight:600;text-transform:none;letter-spacing:0;cursor:pointer}
.linkish .icon{width:14px;height:14px}
.currency-field small{display:block;margin-top:6px;font-size:13px}

/* ---------- Booking pages: glass on the business's own photo ----------------
   The client's booking page and their ticket. Always dark, whatever the site
   theme: the page is the business's photo, and white type on a smoked glass
   sheet is what reads on any photo. Without a photo the business's own card
   colour stands in. On a phone the sheet sits at the bottom of the screen;
   from 900px the business stands on the photo on the left, the sheet on the
   right. Every step uses one rhythm: 20px sides, 8px gaps, 16px corners. */
.gl-main{display:block;padding:0;min-height:100vh}
.gl{--ink:#fff;--ink2:rgba(255,255,255,.74);--ink3:rgba(255,255,255,.52);--glass:rgba(22,14,10,.58);
  --fill:rgba(255,255,255,.08);--fill2:rgba(255,255,255,.15);--line:rgba(255,255,255,.14);--acc:#ff9a52;--on-acc:#1c0e05;
  --pad:20px;--gap:8px;position:relative;min-height:100vh;color:var(--ink);color-scheme:dark;font-family:Manrope,system-ui,sans-serif}
.gl-bg{position:fixed;inset:0;z-index:0;background:radial-gradient(120% 80% at 30% 10%,color-mix(in srgb,var(--brand) 85%,#fff 10%),var(--brand) 45%,#0b0706);
  background-size:cover;background-position:50% 32%;transition:background-image .35s}
.gl-bg::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.30),rgba(0,0,0,.02) 26%,rgba(8,5,3,.55) 60%,rgba(8,5,3,.94))}
.gl-bar{position:fixed;top:0;left:0;right:0;z-index:5;height:72px;display:flex;align-items:center;gap:10px;padding:0 var(--pad)}
.gl-grow{flex:1}
.gl .gl-ctl{height:40px;min-width:40px;display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:0 14px;border-radius:999px;
  background:rgba(0,0,0,.34);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border:1px solid var(--line);
  color:#fff;font:700 14px/1 Manrope,system-ui,sans-serif;text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.gl .gl-ctl.gl-icon{width:40px;padding:0;font-size:20px}
.gl .gl-ctl .icon{width:17px;height:17px}
.gl-chip img{width:24px;height:24px;border-radius:7px;margin-left:-6px}
.gl-layout{position:relative;z-index:1;min-height:100vh;display:flex;flex-direction:column;justify-content:flex-end;padding:72px 10px 10px}
.gl-sheet{position:relative;border-radius:30px;padding:10px var(--pad) var(--pad);background:var(--glass);
  -webkit-backdrop-filter:blur(28px) saturate(1.5);backdrop-filter:blur(28px) saturate(1.5);
  border:1px solid var(--line);box-shadow:0 30px 80px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.16);animation:gl-up .32s cubic-bezier(.2,.8,.2,1)}
@keyframes gl-up{from{opacity:0;transform:translateY(14px)}}
.gl-grab{width:38px;height:5px;border-radius:5px;background:rgba(255,255,255,.28);margin:0 auto 16px}
.gl-biz{display:flex;align-items:center;gap:14px}
.gl-biz img,.gl-initial{width:52px;height:52px;border-radius:15px;flex:none;box-shadow:0 6px 18px rgba(0,0,0,.35);object-fit:cover}
.gl-initial{display:grid;place-items:center;background:var(--fill2);font-size:22px;font-weight:800}
.gl-biz h1{margin:0;font-size:24px;font-weight:800;letter-spacing:-.025em;line-height:1.1;color:#fff}
.gl-biz p{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin:4px 0 0;color:var(--ink2);font-size:13.5px;font-weight:600}
.gl-live{width:7px;height:7px;border-radius:50%;background:#58d68d;box-shadow:0 0 0 3px rgba(88,214,141,.2);margin-right:2px}
.gl-live.off{background:#a9a29d;box-shadow:none}
.gl-lede{display:none}
.gl-hello{display:flex;align-items:center;gap:10px;margin:16px 0 0;padding:10px 12px;border-radius:14px;background:var(--fill);border:1px solid var(--line);font-size:14px;font-weight:600}
.gl-hello .icon{color:var(--acc);flex:none}
.gl-label{display:flex;align-items:center;justify-content:space-between;margin:22px 0 12px;font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ink3)}
.gl-tiles{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap)}
.gl .gl-tile{position:relative;height:164px;padding:0;border-radius:20px;overflow:hidden;border:1px solid var(--line);background:var(--fill);
  color:#fff;text-align:left;cursor:pointer;font:inherit;text-transform:none;letter-spacing:0;box-shadow:none;transition:transform .15s,border-color .15s}
.gl .gl-tile:active{transform:scale(.98)}
.gl .gl-tile.wide{grid-column:span 2;height:124px}
.gl .gl-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.gl .gl-tile::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,transparent 35%,rgba(10,6,4,.88))}
.gl .gl-tile.bare{background:radial-gradient(120% 120% at 20% 0%,color-mix(in srgb,var(--brand) 70%,#fff 18%),color-mix(in srgb,var(--brand) 80%,#000 30%))}
.gl-txt{position:absolute;left:12px;right:12px;bottom:11px;z-index:2}
.gl-txt b{display:block;font-size:15.5px;font-weight:800;line-height:1.2}
.gl-txt small{display:flex;justify-content:space-between;gap:8px;margin-top:3px;color:var(--ink2);font-size:12.5px;font-weight:700}
.gl-txt em{font-style:normal;color:#fff}
.gl-tick{position:absolute;top:10px;right:10px;z-index:2;width:26px;height:26px;border-radius:50%;display:none;place-items:center;
  background:var(--acc);color:var(--on-acc);font-weight:900;font-size:13px}
.gl .gl-tile[aria-pressed="true"]{border-color:var(--acc);box-shadow:inset 0 0 0 2px var(--acc)}
.gl .gl-tile[aria-pressed="true"] .gl-tick{display:grid}
.gl .gl-cta{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;height:56px;margin-top:20px;border:0;border-radius:18px;
  background:#fff;color:#140c08;font:800 16.5px/1 Manrope,system-ui,sans-serif;text-transform:none;letter-spacing:0;text-decoration:none;cursor:pointer;box-shadow:none}
.gl .gl-cta span{opacity:.5}
.gl .gl-cta:disabled{background:rgba(255,255,255,.18);color:rgba(255,255,255,.55);cursor:default}
.gl .gl-cta .icon{width:18px;height:18px}
.gl .gl-cta:not(:disabled):hover{background:#f3ece6}
/* the "when" sheet */
.gl-wait{display:none}
.gl-picked{display:flex;align-items:center;gap:12px;padding:8px 14px 8px 8px;border-radius:20px;background:var(--fill);border:1px solid var(--line)}
.gl-picked img{width:52px;height:52px;border-radius:13px;object-fit:cover;flex:none}
.gl-picked b{display:block;font-size:16px;font-weight:800}
.gl-picked small{color:var(--ink2);font-size:13px;font-weight:600}
.gl .gl-link{margin-left:auto;display:inline-flex;align-items:center;gap:5px;padding:0;min-height:0;border:0;background:none;box-shadow:none;
  color:var(--acc);font:800 13.5px/1.2 Manrope,system-ui,sans-serif;text-transform:none;letter-spacing:0;cursor:pointer}
.gl .gl-link .icon{width:14px;height:14px}
.gl-chips{display:flex;flex-wrap:wrap;gap:var(--gap)}
.gl .gl-pill{height:38px;padding:0 16px;border-radius:999px;display:inline-flex;align-items:center;gap:8px;background:var(--fill);border:1px solid var(--line);
  color:var(--ink2);font:700 14px/1 Manrope,system-ui,sans-serif;text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.gl .gl-pill i{width:22px;height:22px;margin-left:-8px;border-radius:50%;display:grid;place-items:center;font-style:normal;font-size:11px;font-weight:800;background:var(--fill2);color:#fff}
.gl .gl-pill[aria-pressed="true"]{background:#fff;color:#140c08;border-color:#fff}
.gl .gl-pill[aria-pressed="true"] i{background:#140c08}
.gl .gl-arrows{display:flex;gap:6px}
.gl .gl-arrows button{width:30px;height:30px;min-height:0;padding:0;border-radius:9px;display:grid;place-items:center;background:var(--fill);border:1px solid var(--line);
  color:var(--ink2);font-size:15px;box-shadow:none;cursor:pointer}
.gl .gl-arrows button:disabled{opacity:.3;cursor:default}
.gl-label>span:first-child{letter-spacing:.08em}
.gl-week{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.gl .gl-day{height:64px;min-height:0;padding:0;border-radius:16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  background:var(--fill);border:1px solid var(--line);color:#fff;font:inherit;text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.gl .gl-day small{font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--ink3)}
.gl .gl-day b{font-size:18px;font-weight:800;line-height:1}
.gl .gl-day:disabled{opacity:.32;cursor:default}
.gl .gl-day[aria-pressed="true"]{background:var(--acc);border-color:var(--acc);color:var(--on-acc)}
.gl .gl-day[aria-pressed="true"] small{color:rgba(28,14,5,.65)}
.gl .gl-day.pad{visibility:hidden}
.gl .gl-seg{display:grid;grid-template-columns:repeat(3,1fr);padding:4px;margin-top:16px;border-radius:14px;background:var(--fill);border:1px solid var(--line)}
.gl .gl-seg button{height:34px;min-height:0;padding:0;border:0;border-radius:10px;background:none;color:var(--ink2);font:700 13.5px/1 Manrope,system-ui,sans-serif;
  text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.gl .gl-seg button[aria-pressed="true"]{background:var(--fill2);color:#fff;box-shadow:inset 0 0 0 1px var(--line)}
.gl .gl-seg button:disabled{opacity:.35;cursor:default}
.gl-times{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap);margin-top:12px}
.gl .gl-time{height:46px;min-height:0;padding:0;border-radius:14px;display:grid;place-items:center;background:var(--fill);border:1px solid var(--line);
  color:#fff;font:800 15px/1 Manrope,system-ui,sans-serif;font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.gl .gl-time[aria-pressed="true"]{background:#fff;color:#140c08;border-color:#fff}
.gl-empty{margin:14px 0 0;color:var(--ink2);font-size:14px;text-align:center}
.gl-details{display:none;margin-top:4px}
.gl-summary{margin:0 0 14px;padding:12px 14px;border-radius:14px;background:var(--fill);border:1px solid var(--line);font-weight:700;font-size:14.5px}
.gl-field{display:block;margin:0 0 10px;text-transform:none;letter-spacing:0}
.gl-field span{display:block;margin-bottom:6px;font-size:12px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink3)}
.gl-field input{width:100%;height:50px;padding:0 14px;border-radius:14px;border:1px solid var(--line);background:rgba(0,0,0,.28);color:#fff;font:600 16px/1 Manrope,system-ui,sans-serif}
.gl-field input::placeholder{color:var(--ink3)}
.gl-field input:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 3px rgba(255,154,82,.18)}
.gl .form-error{margin:12px 0 0;padding:10px 12px;border-radius:12px;background:rgba(228,115,107,.18);color:#ffd9d4;font-weight:600;font-size:14px}
.gl-fine{margin:12px 0 0;color:var(--ink3);font-size:12.5px;line-height:1.5;text-align:center}
.gl-fine a{color:var(--acc)}
/* steps on a phone: one sheet at a time */
.gl[data-view="service"] .gl-s2{display:none}
.gl[data-view="time"] .gl-s1,.gl[data-view="details"] .gl-s1{display:none}
.gl[data-view="details"] .gl-pick{display:none}
.gl[data-view="details"] .gl-details{display:block}
.gl[data-view="details"] .gl-picked{margin-bottom:14px}
/* the ticket */
.gl-solo{justify-content:flex-end}
.gl-ticket{text-align:center}
.gl-ticket h1{margin:4px 0 0;font-size:26px;font-weight:800;letter-spacing:-.02em;color:#fff}
.gl-badge{width:56px;height:56px;margin:0 auto 12px;border-radius:50%;display:grid;place-items:center;background:var(--acc);color:var(--on-acc)}
.gl-badge .icon{width:26px;height:26px}
.gl-ticket.is-cancelled .gl-badge{background:var(--fill2);color:#fff}
.gl-when-big{display:flex;flex-direction:column;gap:2px;margin:14px 0 6px}
.gl-when-big span{font-size:15px;font-weight:700;color:var(--ink2)}
.gl-when-big b{font-size:44px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.gl-ticket.is-cancelled .gl-when-big{opacity:.5;text-decoration:line-through}
.gl-facts{margin:10px 0 0;text-align:left;border-radius:18px;background:var(--fill);border:1px solid var(--line);padding:2px 14px}
.gl-facts div{display:flex;justify-content:space-between;gap:12px;padding:11px 0;border-bottom:1px solid var(--line)}
.gl-facts div:last-child{border-bottom:0}
.gl-facts dt{color:var(--ink3);font-size:13.5px;font-weight:600}
.gl-facts dd{margin:0;font-weight:800;text-align:right}
.gl-card-offer{margin-top:14px;padding:14px;border-radius:18px;background:rgba(255,154,82,.14);border:1px solid rgba(255,154,82,.35);text-align:left}
.gl-card-offer p{margin:0;font-size:14px;font-weight:600;line-height:1.45}
.gl-card-offer .gl-cta{margin-top:12px}
.gl-note{display:flex;align-items:center;justify-content:center;gap:8px;margin:14px 0 0;color:var(--ink2);font-size:14px;font-weight:600}
.gl-note .icon{color:var(--acc)}
.gl-actions{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap);margin-top:14px}
.gl-actions .gl-btn:only-child,.gl-actions .gl-btn:last-child:nth-child(odd){grid-column:span 2}
.gl .gl-btn{height:50px;display:flex;align-items:center;justify-content:center;gap:8px;border-radius:16px;background:var(--fill);border:1px solid var(--line);
  color:#fff;font:800 14.5px/1 Manrope,system-ui,sans-serif;text-decoration:none}
.gl .gl-btn .icon{width:17px;height:17px}
.gl-btn-main{background:#fff;color:#140c08;border-color:#fff}
.gl-keep{margin:16px 0 0;color:var(--ink3);font-size:13px;line-height:1.5}
.gl-keep .gl-link{margin-left:4px;display:inline-flex}
.gl .gl-danger{width:100%;height:46px;margin-top:12px;border-radius:14px;border:1px solid rgba(228,115,107,.45);background:transparent;color:#ffb3aa;
  font:800 14.5px/1 Manrope,system-ui,sans-serif;text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
/* wide screens: the business on the photo, the booking beside it */
@media(min-width:900px){
  .gl-bar{display:none}
  .gl-bg::after{background:linear-gradient(90deg,rgba(8,5,3,.88) 0%,rgba(8,5,3,.55) 45%,rgba(8,5,3,.35) 100%)}
  .gl-layout{display:grid;grid-template-columns:minmax(0,1fr) 440px;gap:56px;align-items:center;max-width:1180px;margin:0 auto;padding:48px 40px}
  .gl[data-view] .gl-s1,.gl[data-view] .gl-s2{display:block}
  .gl-s1{background:none;border:0;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;padding:0;animation:none}
  .gl-s1 .gl-grab,.gl-s2 .gl-grab,.gl-next{display:none}
  .gl-s1 .gl-biz img,.gl-s1 .gl-initial{width:72px;height:72px;border-radius:20px}
  .gl-s1 .gl-biz h1{font-size:44px}
  .gl-s1 .gl-biz p{font-size:15px}
  .gl-lede{display:block;margin:18px 0 0;max-width:46ch;color:var(--ink2);font-size:16px;line-height:1.55}
  .gl-tiles{grid-template-columns:repeat(3,1fr)}
  .gl .gl-tile,.gl .gl-tile.wide{grid-column:auto;height:150px}
  .gl-s2{position:sticky;top:48px;align-self:start;padding-top:20px;animation:none}
  .gl-wait{display:flex;align-items:center;gap:10px;margin:0;padding:28px 6px;color:var(--ink2);font-weight:600}
  .gl-wait .icon{color:var(--acc)}
  .gl-wait[hidden]{display:none}
  .gl[data-view="details"] .gl-pick{display:block}
  .gl[data-has-time] .gl-details{display:block;margin-top:18px}
  .gl[data-known="1"] .gl-details{display:none}
  .gl-solo{display:flex;align-items:center;justify-content:center}
  .gl-ticket{width:440px}
}
@media(prefers-reduced-motion:reduce){.gl-sheet{animation:none}.gl-bg{transition:none}}
.gl .gl-day:not(:disabled):hover,.gl .gl-time:hover,.gl .gl-pill:hover{border-color:rgba(255,255,255,.4)}
.gl .gl-tile:hover{border-color:rgba(255,255,255,.4)}
.gl .gl-tile[aria-pressed="true"]:hover,.gl .gl-day[aria-pressed="true"]:hover{border-color:var(--acc)}
/* A service without a photo carries its initial, large and faint, so the tile is never just an empty box. */
.gl-mono{position:absolute;top:8px;left:14px;font-size:84px;font-weight:800;line-height:1;color:rgba(255,255,255,.14);letter-spacing:-.04em}
.cover-form{padding:0;margin:var(--s4) 0 0}
.cover-form .photo-drop img{width:96px;height:64px}

/* The rail: Pro tags and the new-bookings count sit at the right edge, in one line. */
.rail-link .pro-tag,.rail-link .nav-badge{margin-left:auto}
.nav-badge{min-width:22px;height:20px;padding:0 7px;border-radius:999px;display:inline-grid;place-items:center;
  background:var(--brass);color:var(--on-brass);font-size:11.5px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brass) 22%,transparent)}
@media(max-width:760px){
  .rail-nav .rail-link .nav-badge{position:absolute;top:3px;left:calc(50% + 6px);margin:0;min-width:17px;height:16px;padding:0 4px;
    font-size:9.5px;box-shadow:0 0 0 2px var(--chrome)}
}

/* The day's arrows: square buttons the height of the date field, centred on it. */
.day-nav{align-items:center}
.day-nav .icon-button{width:44px;height:44px;flex:none;display:grid;place-items:center;border:1px solid var(--hair-hard);
  border-radius:var(--r-control);background:var(--surface-hi);color:var(--ink);padding:0}
.day-nav .icon-button .icon{width:18px;height:18px}
.day-nav .flip{display:grid;transform:scaleX(-1)}
.day-pick input{height:44px}

/* The week strip over the day. */
.week-strip{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;margin:0 0 var(--s4)}
.week-day{display:flex;flex-direction:column;align-items:center;gap:3px;padding:10px 0 9px;border-radius:var(--r-card);
  border:1px solid var(--hair);background:linear-gradient(180deg,var(--surface-hi),var(--surface-lo));color:var(--ink);text-decoration:none}
.week-day small{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.week-day b{font-size:19px;font-weight:700;line-height:1.1}
.week-count{min-width:22px;height:18px;padding:0 6px;border-radius:999px;display:grid;place-items:center;font-size:11px;font-weight:800;
  background:var(--brass-wash);color:var(--brass)}
.week-count.none{background:none;color:var(--ink-4)}
.week-day.today small{color:var(--brass)}
.week-day.on{border-color:var(--brass);background:var(--brass-wash);box-shadow:inset 0 0 0 1px var(--brass)}
.week-day.on .week-count{background:var(--brass);color:var(--on-brass)}

/* The day as a list. */
.board-head-end{display:flex;align-items:center;gap:var(--s3)}
.view-switch{display:inline-flex;padding:3px;border-radius:10px;background:var(--well);border:1px solid var(--hair)}
.view-switch button{min-height:0;height:28px;padding:0 12px;border:0;border-radius:7px;background:none;box-shadow:none;color:var(--ink-3);
  font-size:12.5px;font-weight:700;text-transform:none;letter-spacing:0}
.view-switch button[aria-pressed="true"]{background:var(--surface-hi);color:var(--ink);box-shadow:inset 0 0 0 1px var(--hair-hard)}
.booking-board[data-show="list"] .board-wrap,.booking-board[data-show="list"] .board-legend{display:none}
.booking-board[data-show="grid"] .agenda{display:none}
.agenda{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.agenda-item{width:100%;display:flex;align-items:center;gap:14px;padding:12px 14px;border-radius:var(--r-card);text-align:left;
  border:1px solid var(--hair);border-left:3px solid var(--brass);background:var(--well);color:var(--ink);font:inherit;
  text-transform:none;letter-spacing:0;box-shadow:none;cursor:pointer}
.agenda-time{display:flex;flex-direction:column;flex:none;width:52px;font-family:'JetBrains Mono',ui-monospace,monospace}
.agenda-time b{font-size:15px;color:var(--brass)}
.agenda-time small{font-size:12px;color:var(--ink-3)}
.agenda-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.agenda-body b{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.agenda-body small{font-size:13px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.agenda-status{flex:none;padding:4px 9px;border-radius:999px;font-size:11.5px;font-weight:700;background:var(--brass-wash);color:var(--brass)}
.agenda-item.status-arrived{border-left-color:var(--good)}
.agenda-item.status-arrived .agenda-status{background:color-mix(in srgb,var(--good) 16%,transparent);color:var(--good)}
.agenda-item.status-arrived .agenda-time b{color:var(--good)}
.agenda-item.status-no_show{border-left-color:var(--danger)}
.agenda-item.status-no_show .agenda-status{background:var(--danger-wash);color:var(--danger)}
.agenda-item.status-cancelled{opacity:.55;border-left-color:var(--ink-4)}
.agenda-item.status-cancelled .agenda-body b{text-decoration:line-through}
.agenda-item.status-cancelled .agenda-status{background:none;color:var(--ink-3)}
.agenda-empty{display:flex;align-items:center;justify-content:center;gap:10px;padding:28px 0;color:var(--ink-3)}
@media(max-width:760px){
  .week-strip{gap:5px}
  .week-day{padding:8px 0 7px}
  .week-day b{font-size:17px}
  .booking-board .panel-head{flex-wrap:wrap;gap:8px}
  .board-head-end{width:100%;justify-content:space-between}
}
@media(max-width:760px){
  .page-heading .head-actions .button.primary{flex:1 1 0;min-width:0}
  .page-heading .head-actions .button.square{flex:0 0 46px}
}
.agenda{grid-template-columns:minmax(0,1fr)}.agenda li{min-width:0}

/* The iPhone guide to adding Stemply to the home screen. The chips are
   pictures of Safari's own buttons, so they keep iOS's light look. */
.a2h{position:fixed;inset:0;z-index:90;display:flex;align-items:flex-end;justify-content:center;padding:16px 10px 24px;
  background:rgba(5,6,8,.62);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);animation:a2h-in .25s ease-out}
.a2h-sheet{position:relative;width:100%;max-width:400px;max-height:100%;overflow:auto;border-radius:28px;padding:24px 20px 20px;
  background:#17191D;color:#F2F3F5;border:1px solid rgba(255,255,255,.1);box-shadow:0 30px 80px rgba(0,0,0,.55);
  animation:a2h-up .3s cubic-bezier(.2,.8,.2,1)}
.a2h .a2h-x,.a2h .a2h-x:hover{position:absolute;top:14px;right:14px;width:30px;height:30px;min-height:0;padding:0;border-radius:50%;border:0;
  display:grid;place-items:center;background:rgba(255,255,255,.07);color:#8E939B;font-size:15px;line-height:1;box-shadow:none}
.a2h-head{display:flex;align-items:center;gap:14px;padding-right:30px}
.a2h-icon{width:52px;height:52px;border-radius:13px;flex:none;box-shadow:0 6px 18px rgba(0,0,0,.45)}
.a2h-head h2{margin:0;font-size:19px;font-weight:800;letter-spacing:-.02em;line-height:1.2;color:#F2F3F5}
.a2h-head p{margin:3px 0 0;font-size:13.5px;color:#9BA0A8;line-height:1.35}
.a2h-steps{list-style:none;margin:18px 0 0;padding:0;counter-reset:a2h}
.a2h-steps li{counter-increment:a2h;display:flex;align-items:center;flex-wrap:wrap;gap:8px 10px;padding:11px 0;font-size:15.5px;font-weight:600;line-height:1.3}
.a2h-steps li+li{border-top:1px solid rgba(255,255,255,.06)}
.a2h-steps li::before{content:counter(a2h);width:26px;height:26px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:#C9A96A;color:#1A1405;font-size:13px;font-weight:800;margin-right:2px}
.a2h-chip{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;border-radius:999px;
  background:#F2F2F7;color:#000;font-size:14px;font-weight:600;white-space:nowrap}
.a2h-chip img{width:18px;height:18px;display:block}
.a2h-chip.round{width:32px;padding:0;justify-content:center}
.a2h-foot{margin:12px 0 0;padding:12px 14px;border-radius:14px;background:rgba(201,169,106,.1);color:#D9C08C;font-size:13.5px;line-height:1.4;font-weight:600}
@keyframes a2h-in{from{opacity:0}}
@keyframes a2h-up{from{transform:translateY(24px);opacity:0}}
@media (prefers-reduced-motion:reduce){.a2h,.a2h-sheet{animation:none}}

/* ---------- The till ---------------------------------------------------------
   Frosted glass over the business's own photo, blurred: tabs at the bottom
   with the scanner in the middle, one client as a sheet over everything.
   Always dark, whatever the panel's theme: it sits on a photo. Every button
   is prefixed with .tl so the generic button rules (0,1,1) never win. */
.tl-shell{max-width:none;margin:0;padding:0}
body:has(.tl){background:#0d0b09}
body.tl-lock{overflow:hidden}
body:has(.tl) #toast{top:calc(14px + env(safe-area-inset-top));bottom:auto}
.tl{--tl-mut:rgba(255,255,255,.6);--tl-faint:rgba(255,255,255,.42);--tl-line:rgba(255,255,255,.09);--tl-gold:#F3E2BE;--tl-gold2:#D9B97A;--tl-on-gold:#1A1405;
  position:relative;max-width:560px;min-height:100dvh;margin:0 auto;padding:max(12px,env(safe-area-inset-top)) 16px calc(116px + env(safe-area-inset-bottom));color:#fff}
.tl-bg{position:fixed;inset:-60px;z-index:0;background-color:#140f0b;background-size:cover;background-position:center;filter:blur(42px) saturate(125%) brightness(.6);
  background-image:radial-gradient(40% 30% at 20% 12%,#7a4b23 0%,transparent 70%),radial-gradient(45% 35% at 85% 30%,#4a2e18 0%,transparent 70%),radial-gradient(50% 40% at 30% 75%,#3b2614 0%,transparent 70%),radial-gradient(35% 30% at 80% 88%,#6b3f1c 0%,transparent 70%)}
.tl-bg::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(13,11,9,.25),rgba(13,11,9,.55))}
.tl-view{position:relative;z-index:1}
.tl-glass{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.13);-webkit-backdrop-filter:blur(22px) saturate(140%);backdrop-filter:blur(22px) saturate(140%)}
.tl .icon{width:20px;height:20px}

.tl-top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 4px 0}
.tl-top small{display:block;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:rgba(243,226,190,.65)}
.tl-top strong{display:block;font-size:23px;font-weight:800;letter-spacing:-.02em;margin-top:2px}
.tl .tl-round{width:44px;height:44px;min-height:0;padding:0;border-radius:50%;display:grid;place-items:center;color:var(--tl-gold);font-weight:800;font-size:16px;box-shadow:none;flex:none}
.tl .tl-round:hover{background:rgba(255,255,255,.12)}
.tl-arrows{display:flex;gap:8px}
.tl .tl-flip .icon{transform:scaleX(-1)}

.tl-now{margin-top:16px;border-radius:26px;padding:18px}
.tl-now small{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--tl-gold)}
.tl-now small i{width:8px;height:8px;border-radius:50%;background:var(--tl-gold);box-shadow:0 0 0 4px rgba(243,226,190,.18)}
.tl-now h2{margin:8px 0 0;font-size:26px;font-weight:800;letter-spacing:-.02em;color:#fff}
.tl-now p{margin:3px 0 0;color:var(--tl-mut);font-size:14px}
.tl-now-row{display:flex;gap:8px;margin-top:14px}
.tl .tl-btn{flex:1;min-height:48px;border-radius:16px;gap:8px;font-weight:800;font-size:15px;color:#fff;box-shadow:none}
.tl .tl-btn.tl-glass:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.18)}
.tl .tl-gold,.tl .tl-gold:hover{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));color:var(--tl-on-gold);border:0}
.tl-scan-only{text-align:left}

.tl-label{padding:22px 8px 8px;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.5)}
.tl-list{border-radius:22px;overflow:hidden}
.tl .tl-item{width:100%;display:flex;align-items:center;gap:12px;min-height:64px;padding:12px 16px;border:0;border-radius:0;background:none;box-shadow:none;color:#fff;text-align:left;font-weight:600;white-space:normal}
.tl .tl-item+.tl-item{border-top:1px solid var(--tl-line)}
.tl .tl-item:hover{background:rgba(255,255,255,.05)}
.tl .tl-item:disabled{opacity:.85;cursor:default}
.tl .tl-item.done{opacity:.55}
.tl-item .tm{width:48px;flex:none;font-weight:800;font-size:15.5px}
.tl-item .grow{flex:1;min-width:0}
.tl-item strong{display:block;font-size:15px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tl-item small{display:block;margin-top:1px;font-size:12.5px;font-weight:500;color:var(--tl-mut);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tl-tag{flex:none;height:24px;padding:0 9px;border-radius:999px;display:inline-flex;align-items:center;font-size:12px;font-weight:700;background:rgba(255,255,255,.08);color:var(--tl-mut)}
.tl-tag.arrived{background:rgba(111,207,151,.14);color:#6FCF97}
.tl-tag.no_show{background:rgba(229,115,95,.14);color:#E5735F}
.tl-tag.unmarked{background:rgba(232,180,106,.16);color:#E8B46A}
.tl-tag.cancelled{background:rgba(255,255,255,.05);color:var(--tl-faint);text-decoration:line-through}
.tl-empty{margin:18px 8px 0;color:var(--tl-mut);font-size:14px}
.tl-note{margin:8px 8px 0;font-size:12.5px;color:var(--tl-faint)}
.tl-ini{width:42px;height:42px;border-radius:14px;flex:none;display:grid;place-items:center;background:rgba(255,255,255,.1);font-weight:800;color:var(--tl-gold)}
.tl-dots{display:flex;gap:3px;flex:none}
.tl-dots i{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.18)}
.tl-dots i.on{background:var(--tl-gold)}

.tl-span{display:inline-flex;gap:2px;margin:14px 4px 0;padding:3px;border-radius:999px}
.tl .tl-span button{min-height:34px;padding:0 16px;border-radius:999px;border:0;background:transparent;box-shadow:none;color:rgba(255,255,255,.6);font-weight:700;font-size:14px}
.tl .tl-span button.on{background:rgba(255,255,255,.14);color:#fff}
.tl .tl-back-admin{display:flex;align-items:center;justify-content:center;gap:8px;margin:14px 0 4px;text-decoration:none}
.tl-label.tl-asks{color:#8DBAF4}
.tl-item .tm.tm-date{display:flex;flex-direction:column;width:52px;line-height:1.15}
.tl-item .tm.tm-date small{font-size:12.5px;font-weight:700;color:rgba(255,255,255,.6)}
.tl-day-head{padding:14px 18px 6px;font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--tl-gold)}
.tl-week{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px;margin:16px 0 14px}
.tl .tl-wd{min-height:66px;padding:6px 0;border-radius:16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;box-shadow:none;color:var(--tl-mut);font-weight:700}
.tl .tl-wd:hover{background:rgba(255,255,255,.12)}
.tl-wd small{font-size:11px}
.tl-wd b{font-size:17px;color:#fff}
.tl-wd i{font-style:normal;font-size:10.5px;height:13px;color:var(--tl-gold)}
.tl .tl-wd.today b{color:var(--tl-gold)}
.tl .tl-wd.on{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));border-color:transparent;color:rgba(26,20,5,.7)}
.tl .tl-wd.on b,.tl .tl-wd.on i{color:var(--tl-on-gold)}

.tl-search{display:flex;align-items:center;gap:10px;margin-top:16px;height:52px;padding:0 16px;border-radius:16px;color:var(--tl-mut)}
.tl .tl-search input{flex:1;min-width:0;height:100%;min-height:0;border:0;background:none;color:#fff;font-size:16px;font-weight:600;outline:none;padding:0;box-shadow:none}
.tl-search input::placeholder{color:var(--tl-faint)}

.tl-card{border-radius:22px;padding:16px;margin-top:16px}
.tl-me{display:flex;align-items:center;gap:14px}
.tl-me strong{display:block;font-size:17px}
.tl-me small{display:block;color:var(--tl-mut);font-size:13px;margin-top:2px}
.tl-row{display:flex;align-items:center;flex-wrap:wrap;gap:12px;padding:14px 16px}
.tl-row+.tl-row{border-top:1px solid var(--tl-line)}
.tl-row .grow{flex:1;min-width:0}
.tl-row strong{display:block;font-size:15px}
.tl-row small{display:block;font-size:12.5px;color:var(--tl-mut);margin-top:1px}
.tl .tl-push .tag{all:unset}
.tl-ic{width:38px;height:38px;border-radius:12px;flex:none;display:grid;place-items:center;background:rgba(255,255,255,.1);color:var(--tl-gold)}
.tl .tl-pill{min-height:36px;padding:0 14px;border-radius:12px;font-size:13.5px;font-weight:800;background:rgba(255,255,255,.1);border:0;color:#fff;box-shadow:none;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
.tl .tl-pill:hover{background:rgba(255,255,255,.16)}
.tl .tl-pill.tl-gold:hover{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2))}
.tl .tl-x{width:36px;height:36px;min-height:0;padding:0;border:0;border-radius:12px;background:rgba(255,255,255,.06);color:var(--tl-mut);box-shadow:none}
.tl .tl-x:hover{background:rgba(229,115,95,.15);color:#E5735F}
.tl-wait{flex-basis:100%;margin:0;font-size:12.5px;color:var(--tl-gold)}
.tl .install-hint{margin-top:16px;border-radius:22px;background:rgba(255,255,255,.07);border:1px solid rgba(243,226,190,.3);-webkit-backdrop-filter:blur(22px);backdrop-filter:blur(22px);padding:16px}
.tl .install-hint .button,.tl .install-hint button{box-shadow:none}
.tl-langs{display:flex;flex-wrap:wrap;gap:8px}
.tl-langs a{height:38px;padding:0 14px;border-radius:12px;display:inline-flex;align-items:center;font-size:13.5px;font-weight:700;color:var(--tl-mut);text-decoration:none}
.tl-langs a.on{color:var(--tl-on-gold);background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));border-color:transparent}
.tl-logout{margin-top:24px}
.tl-logout .tl-btn{width:100%}

/* The tab bar: four tabs and the scanner. */
.tl .tl-tabs{position:fixed;z-index:20;left:max(12px,calc(50% - 268px));right:max(12px,calc(50% - 268px));bottom:calc(14px + env(safe-area-inset-bottom));height:72px;border-radius:28px;
  display:grid;grid-template-columns:1fr 1fr 82px 1fr 1fr;align-items:center;padding:0 6px;background:rgba(30,24,19,.55);box-shadow:0 18px 40px rgba(0,0,0,.45)}
.tl .tl-tab{min-height:0;height:60px;padding:0;border:0;border-radius:18px;background:none;box-shadow:none;flex-direction:column;gap:3px;font-size:10.5px;font-weight:700;color:rgba(255,255,255,.55)}
.tl .tl-tab:hover{background:rgba(255,255,255,.06)}
.tl .tl-tab.on{color:var(--tl-gold)}
.tl .tl-tab span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.tl .tl-fab{width:60px;height:60px;min-height:0;margin:0 auto;padding:0;border:0;border-radius:50%;background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));color:var(--tl-on-gold);box-shadow:0 8px 24px rgba(217,185,122,.38)}
.tl .tl-fab:hover{background:linear-gradient(180deg,#fff0cf,var(--tl-gold))}
.tl .tl-fab .icon{width:28px;height:28px}

/* One client, over everything. */
.tl-client{position:fixed;inset:0;z-index:40;overflow-y:auto;overscroll-behavior:contain;background:rgba(13,11,9,.5);-webkit-backdrop-filter:blur(30px) saturate(130%);backdrop-filter:blur(30px) saturate(130%);
  padding:max(12px,env(safe-area-inset-top)) 16px calc(120px + env(safe-area-inset-bottom));animation:tl-up .22s cubic-bezier(.2,.8,.2,1)}
.tl-client>*{max-width:528px;margin-left:auto;margin-right:auto}
.tl-dock.busy{opacity:.6;pointer-events:none}
.tl .tl-dock[hidden]{display:none}
.tl-bar{display:flex;justify-content:space-between;align-items:center;padding:4px 0}
.tl-bar a.tl-round{text-decoration:none}
.tl-hero{margin-top:10px;border-radius:28px;padding:20px 18px 16px;text-align:center}
.tl-hero>strong{display:block;font-size:23px;font-weight:800;letter-spacing:-.02em}
.tl-hero>small{display:block;color:var(--tl-mut);font-size:13.5px;margin-top:2px}
.tl-gauge{position:relative;width:min(270px,100%);margin:14px auto 0}
.tl-gauge svg{display:block;width:100%;height:auto;overflow:visible}
.tl-gauge path{fill:none;stroke-width:16}
.tl-gauge path.off{stroke:rgba(255,255,255,.14)}
.tl-gauge path.on{stroke:var(--tl-gold)}
.tl-gauge path.pop{animation:tl-pop .7s ease-out}
.tl-val{position:absolute;left:0;right:0;bottom:2px;text-align:center}
.tl-val b{display:block;font-size:54px;font-weight:800;letter-spacing:-.04em;line-height:1}
.tl-val span{font-size:13px;color:var(--tl-mut);font-weight:700}
.tl-val.tl-points{position:static;padding:18px 0 6px}
.tl-ends{display:flex;justify-content:space-between;align-items:center;width:min(262px,100%);margin:6px auto 0;font-size:12px;font-weight:700;color:var(--tl-faint)}
.tl-ends .mid{color:var(--tl-gold)}
.tl .tl-reward{width:100%;margin-top:10px;min-height:64px;padding:12px 16px;border-radius:20px;border:1px solid rgba(111,207,151,.35);background:rgba(111,207,151,.14);color:#fff;box-shadow:none;gap:12px;justify-content:flex-start;text-align:left;white-space:normal}
.tl .tl-reward:hover{background:rgba(111,207,151,.2)}
.tl-reward .icon{color:#6FCF97}
.tl-reward span{flex:1;min-width:0}
.tl-reward b{display:block;font-size:15px}
.tl-reward small{display:block;font-size:12.5px;color:var(--tl-mut);font-weight:500}
.tl-reward em{font-style:normal;height:34px;padding:0 12px;border-radius:12px;display:inline-flex;align-items:center;background:#6FCF97;color:#0E1A12;font-size:13px;font-weight:800;flex:none}
.tl-solo{margin-top:10px;border-radius:20px}
.tl-bars{display:flex;gap:4px;margin-top:8px}
.tl-bars i{flex:1;height:5px;border-radius:3px;background:rgba(255,255,255,.15)}
.tl-bars i.on{background:var(--tl-gold)}
.tl .tl-static{min-height:52px;cursor:default}
.tl-static .grow{font-size:14px}
.tl-delta{font-weight:800;color:var(--tl-gold);font-size:14px}
.tl-when{flex:none;width:96px;text-align:right;font-size:12px!important;color:var(--tl-faint)!important}
.tl .tl-undo{display:flex;margin:14px auto 0;min-height:40px;border:0;background:none;box-shadow:none;color:var(--tl-faint);font-size:13.5px;gap:6px}
.tl .tl-undo:hover{background:rgba(255,255,255,.06);color:#fff}
.tl-dock{position:fixed;z-index:41;left:max(12px,calc(50% - 268px));right:max(12px,calc(50% - 268px));bottom:calc(14px + env(safe-area-inset-bottom));padding:10px;border-radius:28px;
  display:grid;grid-template-columns:1fr 1fr 1.5fr;gap:8px;background:rgba(28,22,18,.95);box-shadow:0 18px 40px rgba(0,0,0,.45)}
.tl-dock.two{grid-template-columns:1fr 1.6fr}
.tl-dock.one{grid-template-columns:1fr}
.tl .tl-dk{min-height:62px;padding:0 6px;border:0;border-radius:20px;background:rgba(255,255,255,.1);color:#fff;box-shadow:none;flex-direction:column;gap:4px;font-size:12px;font-weight:800}
.tl .tl-dk:hover{background:rgba(255,255,255,.16)}
.tl .tl-dk.tl-gold{flex-direction:row;gap:8px;font-size:16px}
.tl .tl-dk[hidden]{display:none}

/* An amount, or a package to sell. */
.tl-sheet-wrap{position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center;padding:16px 12px calc(16px + env(safe-area-inset-bottom));background:rgba(0,0,0,.5)}
.tl-sheet{width:100%;max-width:520px;border-radius:28px;padding:20px;background:rgba(30,24,19,.85);display:grid;gap:14px;animation:tl-up .2s ease-out}
.tl-sheet>strong{font-size:19px}
.tl-sheet label{display:grid;gap:6px;font-size:13px;color:var(--tl-mut);font-weight:700}
.tl-sheet input[type=number]{height:56px;border-radius:16px;border:1px solid rgba(255,255,255,.18);background:rgba(0,0,0,.25);color:#fff;font-size:22px;font-weight:800;padding:0 16px}
.tl-choices{display:grid;gap:8px}
.tl .tl-choice{display:flex;align-items:center;gap:12px;min-height:52px;padding:0 14px;border-radius:16px;background:rgba(255,255,255,.07);color:#fff;font-size:15px;font-weight:700}
.tl-choice input{accent-color:var(--tl-gold2);width:18px;height:18px}
.tl-sheet-row{display:flex;gap:8px}

/* The camera. */
.tl-scanner{position:fixed;inset:0;z-index:50;background:#000;padding:max(12px,env(safe-area-inset-top)) 16px 0}
.tl .tl-scanner video{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:cover;border:0;border-radius:0;margin:0}
.tl-scanner .tl-bar{position:relative;z-index:2}
.tl-frame{position:absolute;z-index:1;left:50%;top:42%;width:min(70vw,280px);aspect-ratio:1;transform:translate(-50%,-50%)}
.tl-frame i{position:absolute;width:48px;height:48px;border:4px solid var(--tl-gold)}
.tl-frame i:nth-child(1){left:0;top:0;border-right:0;border-bottom:0;border-radius:20px 0 0 0}
.tl-frame i:nth-child(2){right:0;top:0;border-left:0;border-bottom:0;border-radius:0 20px 0 0}
.tl-frame i:nth-child(3){left:0;bottom:0;border-right:0;border-top:0;border-radius:0 0 0 20px}
.tl-frame i:nth-child(4){right:0;bottom:0;border-left:0;border-top:0;border-radius:0 0 20px 0}
.tl-frame b{position:absolute;left:16px;right:16px;top:50%;height:2px;background:linear-gradient(90deg,transparent,var(--tl-gold),transparent);box-shadow:0 0 14px var(--tl-gold2);animation:tl-sweep 2s ease-in-out infinite}
.tl-scan-hint{position:absolute;z-index:1;left:0;right:0;top:calc(42% + min(35vw,140px) + 20px);text-align:center;font-size:15px;font-weight:700;color:rgba(255,255,255,.85);text-shadow:0 1px 8px rgba(0,0,0,.6)}
.tl-code{position:absolute;z-index:2;left:16px;right:16px;bottom:calc(24px + env(safe-area-inset-bottom));max-width:528px;margin:0 auto;display:flex;gap:8px;padding:8px;border-radius:22px;background:rgba(30,24,19,.6)}
.tl .tl-code input{flex:1;min-width:0;height:44px;min-height:0;border:0;box-shadow:none;background:none;color:#fff;font-size:16px;font-weight:700;padding:0 10px;outline:none;letter-spacing:.06em;text-transform:uppercase}
.tl-code input::placeholder{text-transform:none;letter-spacing:0;color:var(--tl-faint)}
.tl .tl-dock{background:#1d1713}
/* One booking's actions, and the day and time to move it to. */
.tl-bsheet{max-height:calc(100dvh - 32px);overflow-y:auto}
.tl-bs-head{display:flex;align-items:flex-start;gap:12px}
.tl-bs-head small{display:block;font-size:12.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--tl-gold)}
.tl-bs-head strong{display:block;font-size:22px;font-weight:800;letter-spacing:-.02em;margin-top:4px}
.tl-bs-head span{display:block;color:var(--tl-mut);font-size:14px;margin-top:2px}
.tl-bsheet [data-b-actions]{display:grid;gap:10px}
.tl-bs-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.tl .tl-bs-grid .tl-btn{min-height:52px;font-size:14px;padding:0 10px}
.tl .tl-bs-grid .tl-btn[hidden]{display:none}
.tl .tl-bs-grid .tl-wide{grid-column:1/-1}
.tl .tl-btn.tl-danger{color:#F0A49A}
.tl .tl-btn.tl-danger:hover{background:rgba(229,115,95,.14)}
.tl-mover{display:grid;gap:12px}
.tl-mover[hidden]{display:none}
.tl-svcs{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.tl-svcs[hidden]{display:none}
.tl-svcs::-webkit-scrollbar{display:none}
.tl .tl-svc{flex:none;max-width:70%;min-height:52px;padding:6px 14px;border-radius:16px;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:1px;box-shadow:none;color:var(--tl-mut);text-align:left}
.tl .tl-svc b{font-size:14px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.tl .tl-svc small{font-size:11.5px;font-weight:700}
.tl .tl-svc:hover{background:rgba(255,255,255,.12)}
.tl .tl-svc.on{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));border-color:transparent;color:rgba(26,20,5,.7)}
.tl .tl-svc.on b{color:var(--tl-on-gold)}
.tl-days{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.tl-days::-webkit-scrollbar{display:none}
.tl .tl-days .tl-wd{flex:none;width:52px;min-height:60px}
.tl-times{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;max-height:228px;overflow-y:auto}
.tl .tl-time{min-height:44px;padding:0;border-radius:14px;font-size:15px;font-weight:800;color:#fff;box-shadow:none}
.tl .tl-time:hover{background:rgba(255,255,255,.14)}
.tl .tl-time.current{border-color:rgba(243,226,190,.5);color:var(--tl-gold)}
.tl .tl-time.on{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));color:var(--tl-on-gold);border-color:transparent}
.tl [data-now-name]{cursor:pointer}
/* Gold wins over the shapes it sits on. */
.tl .tl-gold.tl-dk,.tl .tl-gold.tl-dk:hover,.tl .tl-gold.tl-pill,.tl .tl-gold.tl-pill:hover{background:linear-gradient(180deg,var(--tl-gold),var(--tl-gold2));color:var(--tl-on-gold)}
@keyframes tl-up{from{transform:translateY(18px);opacity:0}}
@keyframes tl-pop{0%{stroke:#fff;stroke-width:22}100%{stroke-width:16}}
@keyframes tl-sweep{0%,100%{transform:translateY(-70px)}50%{transform:translateY(70px)}}
@media (prefers-reduced-motion:reduce){.tl-client,.tl-sheet,.tl-gauge path.pop,.tl-frame b{animation:none}}
@media (min-width:700px){.tl{padding-top:28px}}
/* Several Abos on one card at the till: a row each, the first one marked. */
.tl-abo .tl-abo-n{font-weight:700;font-size:15px;white-space:nowrap}
.tl-abo strong .tl-tag{font-style:normal;font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:#2a2116;background:var(--brass);border-radius:6px;padding:1px 6px;margin-left:8px;vertical-align:2px}
.tl-abo-add{width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer}
/* Sending a customer's card again, above their details. */
.card-resend{display:flex;flex-direction:column;gap:6px;margin:0 0 var(--s4)}
.card-resend .button{align-self:flex-start}
.card-resend p{margin:0;font-size:13px}

/* Card history: Abo purchases stand out, the long list scrolls. */
#customer-history .table-wrap{max-height:460px;overflow-y:auto}
.history-table tr.is-abo td{color:var(--brass-hi);font-weight:600}
.tl .tl-item.tl-bought .grow,.tl .tl-item.tl-bought .tl-delta{color:var(--tl-gold,#e9d3a3)}
.tl .tl-item.tl-more{justify-content:center;min-height:48px;color:rgba(255,255,255,.7);font-weight:600;cursor:pointer}

/* A booking request waits for an answer: dashed, in the warm "to do" tone. */
.board-item.status-requested{border-left-color:#6AA6F0;border-left-style:dashed;background:rgba(106,166,240,.10)}
.board-item.status-requested b{color:#6AA6F0}
.board-legend .status-requested::before{background:#6AA6F0}
.agenda-item.status-requested{border-left-color:#6AA6F0;border-left-style:dashed}
.agenda-item.status-requested .agenda-status{background:rgba(106,166,240,.16);color:#6AA6F0}
.tl-tag.requested{background:rgba(106,166,240,.16);color:#6AA6F0}
.tl-bsheet [data-b-request]{margin-bottom:10px}

/* The booking client picker opens as a list of everyone: keep it scrollable. */
.client-pick .picker-results{max-height:320px;overflow-y:auto}
.tl .tl-note[data-b-request]{display:flex;align-items:center;gap:8px;margin:0 4px 12px;font-size:14px;color:#6AA6F0}
.client-pick .picker-results button{justify-content:flex-start;text-align:left}
.client-pick .picker-results button span{display:flex;flex-direction:column;align-items:flex-start}

/* Day, week, month. */
.span-switch{display:inline-flex;gap:2px;padding:3px;margin:0 0 var(--s3);border:1px solid var(--hair);border-radius:999px;background:var(--well)}
.span-switch a{padding:6px 14px;border-radius:999px;font-size:13.5px;font-weight:600;color:var(--ink-3);text-decoration:none}
.span-switch a.on{background:var(--surface-hi);color:var(--ink)}
.period-week .week-block{padding:var(--s2) 0;border-top:1px solid var(--hair-soft)}
.period-week .week-block:first-of-type{border-top:0}
.period-week .week-block-head{display:flex;justify-content:space-between;align-items:center;padding:6px 2px;color:var(--ink);text-decoration:none}
.period-week .week-block.today .week-block-head b{color:var(--brass-hi)}
.period-week .agenda{margin-top:4px}
.month-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}
.month-wd{font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding:4px 0}
.month-cell{position:relative;display:flex;flex-direction:column;gap:2px;min-height:96px;padding:6px;border:1px solid var(--hair-soft);border-radius:8px;
  background:var(--well);color:var(--ink);text-decoration:none;overflow:hidden}
.month-cell:hover{border-color:var(--hair-hard)}
.month-cell.out{opacity:.4}
.month-cell.today{border-color:var(--brass)}
.month-cell b{font-size:13px}
.month-cell.today b{color:var(--brass-hi)}
.month-entry{font-size:11.5px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:1px 4px;border-radius:4px;background:var(--brass-wash)}
.month-entry.status-requested{background:rgba(106,166,240,.16);color:#6AA6F0}
.month-entry.status-arrived{color:var(--good)}
.month-entry.status-no_show{color:var(--danger)}
.month-more{font-size:11px;color:var(--ink-3)}
.month-count{display:none}
@media (max-width: 720px){
  .month-cell{min-height:54px;align-items:center;padding:6px 2px}
  .month-entry,.month-more{display:none}
  .month-count{display:grid;place-items:center;min-width:20px;height:20px;padding:0 5px;border-radius:999px;font-size:11px;font-weight:700;
    background:var(--brass-wash);color:var(--brass-hi)}
  .month-cell.asks .month-count{background:rgba(106,166,240,.18);color:#6AA6F0}
}

/* The card sent from the owner's phone: WhatsApp first, SMS beside it. */
.send-card-row{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s3)}
#result-body .send-card-row .button{flex:1 1 140px;display:flex;align-items:center;justify-content:center;font-family:inherit;font-size:15px;text-align:center;word-break:normal}
.gl .gl-ok{margin:14px 0 4px}
/* Who takes the booking, on its own line and never cut short. */
.agenda-body small.agenda-staff{white-space:normal;overflow:visible;color:var(--brass-hi);font-weight:600}

/* A customer's bookings: a link per row, coming ones first. */
.customer-bookings .list-label{margin:var(--s3) 0 var(--s2);font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.customer-bookings .agenda-item{text-decoration:none}
.customer-bookings .agenda-time{width:58px}
.customer-bookings .agenda-body small{white-space:normal}

/* Printing the calendar: the day as its grid of staff columns, the week and
   the month as they are, on white paper without the app around them. */
.print-button{display:inline-grid;place-items:center;width:34px;height:34px;padding:0;border-radius:10px}
.print-button svg{width:18px;height:18px}
@media print{
  @page{margin:10mm}
  *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
  html,body,.shell,.work,main{display:block!important;height:auto!important;min-height:0!important;overflow:visible!important;background:#fff!important}
  .shell{grid-template-columns:1fr!important}
  .rail,.rail-more,.topbar,.span-switch,.week-strip,.view-switch,.print-button,.fresh-bookings,#add-booking,.push-nudge,
  .pro-note,dialog,#toast,.head-actions,.print-hint,.month-count,footer,canvas{display:none!important}
  html::before,html::after,body::before,body::after,.shell::before,.work::before{display:none!important}
  .page-heading{margin-bottom:12px!important;padding-bottom:0!important;border:0!important}
  .board{--m:.95px}
  main.container{max-width:none!important;padding:0!important;margin:0!important}
  .panel{box-shadow:none!important;background:#fff!important;border:1px solid #d5d8dd!important;break-inside:auto}
  .booking-board .agenda{display:none!important}
  .booking-board .board-wrap{display:block!important;overflow:visible!important;margin:0!important;padding:0!important}
  .booking-board .board-legend{display:flex!important}
  .board-col{flex:1 1 0!important;min-width:0!important}
  /* A 45 minute booking is about 40px on paper: name and service still fit. */
  .board-item{padding:2px 7px!important;gap:0!important;box-shadow:none!important}
  .board-item b{font-size:11px}
  .board-line span{font-size:12px}
  .board-item small{font-size:11px;line-height:1.25}
  .board-item,.agenda-item,.week-block-head,.month-cell{break-inside:avoid}
  .month-entry,.month-more{display:block!important}
  .month-cell{min-height:90px!important;align-items:stretch!important}
  .agenda-item{border:1px solid #d5d8dd;background:#fff!important}
  .period-week .agenda{gap:3px!important}
  .period-week .agenda-item{padding:4px 10px!important;min-height:0!important}
  .period-week .agenda-body{flex-direction:row!important;flex-wrap:wrap;align-items:baseline;gap:0 10px!important}
  .period-week .agenda-time{flex-direction:row!important;gap:6px!important;min-width:110px}
  .period-week .week-block-head{padding:6px 0 4px!important}
}

/* The week as a grid: a column a day, overlapping bookings in lanes. */
.booking-board[data-show="grid"] .week-list{display:none}
.period-week[data-show="list"] .board-wrap{display:none}
.board-week .board-col{flex:1 0 132px;min-width:132px}
.board-week a.board-head{color:inherit;text-decoration:none}
.board-week .board-col.today .board-head{color:var(--brass)}
.board-item[style*="--lanes"]{left:calc(4px + (100% - 8px) * var(--lane) / var(--lanes));right:auto;width:calc((100% - 8px) / var(--lanes) - 2px)}
/* A tap on an empty time in the grid starts a booking there. */
.board .board-track[data-staff],.board .board-track[data-day]{cursor:copy}
/* The customer field is a list to pick from: it gets the arrows a select has. */
.client-pick input[data-client-search]{padding-right:38px;background-repeat:no-repeat;background-position:right 13px center;background-size:12px 16px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 16' fill='none' stroke='%239aa1ab' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6 6 2.5 9.5 6M2.5 10 6 13.5 9.5 10'/%3E%3C/svg%3E")}
.check + .check{margin-top:4px}

/* The till's new booking sheet and the owner's typed time. */
.tl .tl-bookform{display:grid;gap:10px;max-height:calc(100 * var(--vh, 1vh) - 40px);overflow-y:auto}
.tl .tl-bookform .field{display:grid;gap:4px;margin:0}
.tl .tl-bookform label{font-size:12px;font-weight:700;color:rgba(255,255,255,.6)}
.tl .tl-bookform input:not([type=checkbox]):not([type=hidden]),.tl .tl-bookform select{width:100%;min-height:44px;padding:0 12px;border-radius:12px;
  background-color:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);color:#fff;font-size:16px}
.tl .tl-bookform select option{color:#111}
.tl .tl-bookform .check{display:flex;align-items:center;gap:8px;font-size:14px;color:rgba(255,255,255,.8)}
.tl .tl-bookform .picker-results{display:grid;max-height:240px;overflow-y:auto;border-radius:12px;background:rgba(20,15,11,.96);border:1px solid rgba(255,255,255,.14)}
.tl .tl-bookform .picker-results button{display:flex;flex:none;height:auto;min-height:52px;padding:8px 12px;border:0;border-radius:0;border-bottom:1px solid rgba(255,255,255,.08);background:transparent;box-shadow:none;color:#fff;text-align:left;line-height:1.3}
.tl .tl-bookform .picker-results button span{display:flex;flex-direction:column;gap:2px}
.tl .tl-bookform .picker-results small{color:rgba(255,255,255,.55)}
.tl .tl-free{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 12px;border-radius:14px;font-size:14px;color:rgba(255,255,255,.75)}
.tl .tl-free span{text-transform:none;letter-spacing:0;font-size:14px;font-weight:600;line-height:1.3}
.tl .tl-free input{min-height:38px;padding:0 10px;border-radius:10px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);color:#fff;font-size:16px}
@media print{
  .period-week .week-list{display:block!important}
  .period-week .agenda{display:grid!important}
  .period-week .board-wrap{display:none!important}
}

/* The owner's calendar inside the till: the panel in a frame above the tab
   bar, without its own navigation, on the till's background. */
.tl .tl-cal{position:fixed;z-index:15;left:0;right:0;top:0;bottom:calc(96px + env(safe-area-inset-bottom))}
.tl .tl-cal[hidden]{display:none}
.tl .tl-cal iframe{display:block;width:100%;height:100%;border:0;background:transparent}
body.tl-cal-on [data-view="records"] > :not([data-cal]){visibility:hidden}
html.embedded,html.embedded body{background:transparent!important}
html.embedded::before,html.embedded::after,html.embedded body::before,html.embedded body::after{display:none!important}
.embedded .rail,.embedded .rail-more,.embedded footer{display:none!important}
.embedded .shell{display:block;min-height:0}
.embedded .work{padding:0!important;min-height:0}
.embedded main.container{padding-top:10px!important;padding-bottom:24px!important}
.embedded .page-heading .eyebrow,.embedded .page-heading h1{display:none}
.embedded .page-heading{margin-bottom:12px;padding-bottom:0;border:0}
.embedded a[href="/cashier"]{display:none!important}
.embedded .push-nudge,.embedded [data-push-nudge]{display:none!important}
