/* ============================================================
   The Gentleman's Barbershop
   Shared stylesheet for the customer app (index.html) and the
   owner dashboard (admin.html). Plain CSS, no build step.

   Paths are relative to this file: ../img, ../fonts.
   ============================================================ */

@font-face{
  font-family:'Figtree Variable';
  font-style:normal;font-display:swap;font-weight:300 900;
  src:url("../fonts/figtree-variable.woff2") format("woff2-variations");
}

/* ============================================================
   TOKENS — white, greys, no outlines
   ============================================================ */
:root{
  --font:"Figtree Variable",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --r-xs:8px; --r-sm:10px; --r-md:12px; --r-lg:16px; --r-xl:22px; --r-full:999px;
  --ease: cubic-bezier(.32,.72,0,1);
}

html[data-theme="light"]{
  --bg:#FFFFFF;
  --surface:#F7F7F7;
  --surface-2:#F0F0F0;
  --surface-3:#E9E9E9;
  --ink:#1C1C1C;
  --ink-2:#6A6A6A;
  --ink-3:#A0A0A0;
  --hair:rgba(0,0,0,.075);
  --btn:#1C1C1C;
  --on-btn:#FFFFFF;
  --live:#2E7D51;
  --shadow:0 8px 28px rgba(0,0,0,.10), 0 2px 6px rgba(0,0,0,.05);
  --shadow-sm:0 2px 10px rgba(0,0,0,.09);
  /* elevation — subtle, so grouped content lifts off the white */
  --elev:0 1px 2px rgba(0,0,0,.045), 0 6px 16px rgba(0,0,0,.055);
  --elev-sm:0 1px 2px rgba(0,0,0,.045), 0 2px 6px rgba(0,0,0,.04);
  --elev-img:0 2px 4px rgba(0,0,0,.07), 0 10px 24px rgba(0,0,0,.10);
  --frame:#E4E4E4;
  --scrim:rgba(0,0,0,.36);
  --glass:rgba(255,255,255,.92);
}

html[data-theme="dark"]{
  --bg:#0F0F0F;
  --surface:#1A1A1A;
  --surface-2:#232323;
  --surface-3:#2C2C2C;
  --ink:#F3F3F3;
  --ink-2:#A6A6A6;
  --ink-3:#727272;
  --hair:rgba(255,255,255,.09);
  --btn:#FFFFFF;
  --on-btn:#111111;
  --live:#5FCB8D;
  --shadow:0 10px 40px rgba(0,0,0,.7), 0 2px 8px rgba(0,0,0,.5);
  --shadow-sm:0 2px 12px rgba(0,0,0,.5);
  /* elevation — on near-black, shadow does less work, so it stays quieter */
  --elev:0 1px 2px rgba(0,0,0,.55), 0 6px 18px rgba(0,0,0,.45);
  --elev-sm:0 1px 3px rgba(0,0,0,.5);
  --elev-img:0 2px 6px rgba(0,0,0,.6), 0 10px 26px rgba(0,0,0,.45);
  --frame:#242424;
  --scrim:rgba(0,0,0,.6);
  --glass:rgba(15,15,15,.9);
}


/* photography — shared across both themes */
:root{
  --shop:url("../img/shop.jpg");
  --img:url("../img/kieron.jpg");
  --img-2:url("../img/ash.jpg");
  --img-3:url("../img/paul.jpg");
  --work-1:url("../img/work-1.jpg");
  --work-2:url("../img/work-2.jpg");
  --work-3:url("../img/work-3.jpg");
}

*{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
body{
  margin:0; font-family:var(--font);
  /* --bg, not --surface. The shell covers the viewport, so this is only
     ever seen if something has gone wrong with its height — and when that
     happened it read as a grey band under the tab bar. Matching the app
     means the worst case is invisible rather than obviously broken. */
  background:var(--bg); color:var(--ink);
  -webkit-font-smoothing:antialiased;
  letter-spacing:-.01em;
  transition:background .35s var(--ease), color .35s var(--ease);
}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;}
::-webkit-scrollbar{width:0;height:0;}

/* ============================================================
   APP SHELL
   The prototype ran inside a phone mockup on desktop. That frame,
   its fake status bar, notch, home indicator and URL bar are gone:
   the full-bleed layout is now the only layout, at every width.
   ============================================================ */
/* Pinned to the top of the viewport, with its height measured rather than
   inferred. See the inlined <style> in base.html — that copy is the one
   that must win on a cold load, and this one exists so the rule is not a
   secret kept in a template.

   The history: height:100svh looked right until the app was drawn under
   the status bar, at which point iOS reports svh *without* the top inset
   and the shell came up about 60px short — the tab bar floating above a
   strip of page background. Detecting standalone was the wrong fix twice:
   Safari doesn't reliably match @media (display-mode: standalone), and
   navigator.standalone only helps after the JS has run. window.innerHeight
   needs neither. */
.app{
  position:fixed;top:0;left:0;right:0;
  height:100vh;height:100svh;height:var(--vph, 100svh);
  display:flex;flex-direction:column;
  background:var(--bg);overflow:hidden;
  transition:background .35s var(--ease);
}

/* keeps scrolled content from colliding with the status bar on a
   phone that has drawn the app under it (viewport-fit=cover +
   black-translucent). It has to be opaque for the full height of the
   inset, not just faded, or a line of text passes behind the clock. */
.topfade{
  position:absolute;top:0;left:0;right:0;z-index:28;pointer-events:none;
  height:calc(env(safe-area-inset-top,0px) + 20px);
  background:linear-gradient(180deg,
    var(--bg) 0%,
    var(--bg) calc(100% - 20px),
    color-mix(in srgb,var(--bg) 55%, transparent) calc(100% - 8px),
    transparent 100%);
  transition:opacity .3s var(--ease);
}
/* while the hero photo is behind it, the fade would only muddy the picture */
.app.overhero .topfade{opacity:0;}

.viewport{flex:1;overflow-y:auto;overscroll-behavior:contain;position:relative;}
.pane{display:none;padding:calc(env(safe-area-inset-top,0px) + 16px) 24px 30px;animation:fade .32s var(--ease);}
.pane--bleed{padding-top:0;}
.pane.on{display:block;}
@keyframes fade{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}

/* the dashboard has no tab bar, so the toast sits lower */
body.owner .toast{bottom:calc(env(safe-area-inset-bottom,0px) + 24px);}

/* plain links between the two pages, styled as ordinary rows */
/* Several controls are real links now that the data is real — the
   Directions tile, the Google buttons — so they must not pick up the
   default underline and blue. */
a.row,a.madeby__link,a.btn,.quick a{text-decoration:none;color:inherit;}
a.btn{color:var(--on-btn);}
a.btn--soft{color:var(--ink);}

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

/* ============================================================
   TAB BAR
   ============================================================ */
.tabbar{
  flex:none;display:flex;padding:10px 6px calc(env(safe-area-inset-bottom,0px) + 12px);position:relative;
  background:var(--glass);backdrop-filter:blur(24px) saturate(160%);
}
.tabbar::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:var(--hair);}
.tabbar button{
  flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;padding:5px 0;
  font-size:10px;font-weight:500;color:var(--ink-3);transition:color .2s;
}
.tabbar button svg{width:23px;height:23px;stroke-width:1.6;}
.tabbar button.on{color:var(--ink);font-weight:600;}
.tabbar button.on svg{stroke-width:2.1;}
/* ============================================================
   TYPE + PRIMITIVES  (Airbnb-ish: flat, no outlines)
   ============================================================ */
.title{font-size:26px;font-weight:600;line-height:1.18;letter-spacing:-.028em;margin:8px 0 0;}
.sub{font-size:15px;color:var(--ink-2);line-height:1.45;margin:6px 0 0;letter-spacing:-.005em;}
h3.hd{font-size:20px;font-weight:600;letter-spacing:-.026em;margin:0 0 14px;}
.sec{margin-top:30px;}
.sec--tight{margin-top:22px;}

.hair{height:1px;background:var(--hair);margin:26px 0;}
.hair--flush{margin:0;}

.fill{background:var(--surface);border-radius:var(--r-lg);padding:18px;box-shadow:var(--elev-sm);}

.btn{
  display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  padding:15px;border-radius:var(--r-full);background:var(--btn);color:var(--on-btn);
  font-size:15.5px;font-weight:600;letter-spacing:-.01em;
  box-shadow:var(--elev);
  transition:transform .12s var(--ease),opacity .2s,box-shadow .2s var(--ease);
}
.btn:active{transform:scale(.98);box-shadow:var(--elev-sm);}
.btn:hover{opacity:.88;}
.btn--soft{background:var(--surface-2);color:var(--ink);box-shadow:var(--elev-sm);}

.pill{
  display:inline-flex;align-items:center;gap:7px;padding:7px 13px;
  border-radius:var(--r-full);background:var(--surface-2);
  font-size:12.5px;font-weight:600;color:var(--ink-2);
}
.live{width:7px;height:7px;border-radius:50%;background:var(--live);position:relative;flex:none;}
.live::after{content:"";position:absolute;inset:-3px;border-radius:50%;background:var(--live);opacity:.28;animation:p 2.4s infinite var(--ease);}
@keyframes p{0%{transform:scale(.6);opacity:.35}70%,100%{transform:scale(1.7);opacity:0}}

/* list rows — hairline separated, no boxes */
.list{display:flex;flex-direction:column;}
.row{
  display:flex;align-items:center;gap:14px;width:100%;text-align:left;
  padding:16px 0;position:relative;
  transition:opacity .15s;
}
.row + .row::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:var(--hair);}
.row:active{opacity:.6;}
.row__t{display:block;font-size:15.5px;font-weight:500;letter-spacing:-.012em;}
.row__s{display:block;font-size:13.5px;color:var(--ink-2);margin-top:3px;line-height:1.4;}
.row__r{margin-left:auto;display:flex;align-items:center;gap:8px;font-size:16px;font-weight:600;}
.chev{color:var(--ink-3);flex:none;}
.muted{color:var(--ink-2);font-size:14px;line-height:1.55;}
.tiny{color:var(--ink-3);font-size:12.5px;line-height:1.5;}

/* thumbnails + photos */
.ph{
  background:var(--img);background-size:cover;background-position:center 22%;
  border-radius:var(--r-md);position:relative;overflow:hidden;flex:none;
  box-shadow:var(--elev-img);
}
.ph--b{background-image:var(--img-2);}
.ph--c{background-image:var(--img-3);}
.ph--d{background-image:var(--shop);background-position:center 46%;}
.ph--w1{background-image:var(--work-1);background-position:center 40%;}
.ph--w2{background-image:var(--work-2);background-position:center 38%;}
.ph--w3{background-image:var(--work-3);background-position:center 40%;}
.thumb{width:56px;height:56px;border-radius:var(--r-md);}
.avatar{width:44px;height:44px;border-radius:50%;background:var(--img);background-size:cover;background-position:center 20%;flex:none;}

/* toggle */
.sw{width:50px;height:30px;border-radius:var(--r-full);flex:none;background:var(--surface-3);position:relative;transition:background .3s var(--ease);}
.sw::after{content:"";position:absolute;top:3px;left:3px;width:24px;height:24px;border-radius:50%;background:var(--bg);box-shadow:var(--shadow-sm);transition:transform .3s var(--ease);}
.sw.on{background:var(--btn);}
.sw.on::after{transform:translateX(20px);}

/* ============================================================
   HOME
   ============================================================ */
/* full-bleed hero with the title sat over the bottom of the photo */
.hero{
  position:relative;height:52vh;min-height:330px;margin:0 -24px 0;
  background:var(--shop) center 42%/cover no-repeat;
  display:flex;align-items:flex-end;
}
/* progressive blur — five stacked layers, each blurrier and masked to start
   lower down, so the photo dissolves into the type instead of stopping dead */
.hero__blur{position:absolute;left:0;right:0;bottom:0;height:50%;z-index:1;pointer-events:none;}
.hero__blur span{position:absolute;inset:0;display:block;}
.hero__blur span:nth-child(1){
  -webkit-backdrop-filter:blur(0.8px);backdrop-filter:blur(0.8px);
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 18%);
          mask-image:linear-gradient(180deg,transparent 0%,#000 18%);}
.hero__blur span:nth-child(2){
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  -webkit-mask-image:linear-gradient(180deg,transparent 18%,#000 36%);
          mask-image:linear-gradient(180deg,transparent 18%,#000 36%);}
.hero__blur span:nth-child(3){
  -webkit-backdrop-filter:blur(4.5px);backdrop-filter:blur(4.5px);
  -webkit-mask-image:linear-gradient(180deg,transparent 36%,#000 55%);
          mask-image:linear-gradient(180deg,transparent 36%,#000 55%);}
.hero__blur span:nth-child(4){
  -webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);
  -webkit-mask-image:linear-gradient(180deg,transparent 55%,#000 74%);
          mask-image:linear-gradient(180deg,transparent 55%,#000 74%);}
.hero__blur span:nth-child(5){
  -webkit-backdrop-filter:blur(17px);backdrop-filter:blur(17px);
  -webkit-mask-image:linear-gradient(180deg,transparent 74%,#000 92%);
          mask-image:linear-gradient(180deg,transparent 74%,#000 92%);}

/* darkening sits on top of the blur, not under it */
.hero__grad{
  position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(0,0,0,.42) 0%,
    rgba(0,0,0,.10) 24%,
    rgba(0,0,0,.00) 44%,
    rgba(0,0,0,.14) 58%,
    rgba(0,0,0,.36) 72%,
    rgba(0,0,0,.60) 86%,
    rgba(0,0,0,.74) 100%);
}
.hero__in{position:relative;z-index:3;padding:0 24px 26px;width:100%;}
.hero__in h1{
  font-size:34px;font-weight:700;letter-spacing:-.042em;line-height:1.04;
  margin:0;color:#fff;text-shadow:0 1px 18px rgba(0,0,0,.28);
  /* The name comes from the database now, so the line break can't be typed
     in by hand. balance splits it evenly instead of leaving one orphan word;
     browsers without it just wrap normally, which is fine. */
  text-wrap:balance;max-width:11ch;
}
/* Unless he typed his own breaks, in which case his layout wins outright
   and the balancing would only fight it. */
.hero__in h1.h1--manual{text-wrap:initial;max-width:none;}
.hero__meta{display:flex;align-items:center;gap:8px;margin-top:14px;flex-wrap:wrap;}
.pill--over{
  background:rgba(255,255,255,.17);color:#fff;
  -webkit-backdrop-filter:blur(10px) saturate(160%);backdrop-filter:blur(10px) saturate(160%);
  box-shadow:0 1px 10px rgba(0,0,0,.16);
}

.busy{background:var(--surface);border-radius:var(--r-lg);padding:20px;margin-top:24px;box-shadow:var(--elev);}
.busy__top{display:flex;align-items:baseline;gap:10px;}
.busy__n{font-size:40px;font-weight:600;letter-spacing:-.04em;line-height:1;font-variant-numeric:tabular-nums;}
.busy__lbl{font-size:16px;font-weight:500;letter-spacing:-.015em;}
.busy__bar{height:4px;border-radius:4px;background:var(--surface-3);margin-top:16px;overflow:hidden;}
.busy__fill{height:100%;border-radius:4px;background:var(--ink);transition:width .5s var(--ease);}

/* who's in — horizontal scroller */
.crew{display:flex;gap:14px;overflow-x:auto;margin:0 -24px;padding:2px 24px 6px;scroll-snap-type:x proximity;scroll-padding-left:24px;}
.crewcard{width:106px;flex:none;scroll-snap-align:start;text-align:left;}
.crewcard .ph{width:106px;height:106px;border-radius:var(--r-md);}
.crewcard__n{font-size:15px;font-weight:500;margin-top:10px;letter-spacing:-.012em;}
.crewcard__s{font-size:13.5px;color:var(--ink-2);margin-top:1px;}
.crewcard.off .ph{opacity:.34;filter:grayscale(1);}
.crewcard.off .crewcard__n,.crewcard.off .crewcard__s{opacity:.42;}

.quick{display:flex;gap:9px;}
.quick button,.quick a{
  flex:1;padding:15px 6px;border-radius:var(--r-md);background:var(--surface);
  display:flex;flex-direction:column;align-items:center;gap:8px;
  font-size:11.5px;font-weight:500;color:var(--ink);
  box-shadow:var(--elev-sm);
  transition:background .2s,transform .12s var(--ease),box-shadow .2s var(--ease);
}
.quick button:hover,.quick a:hover{background:var(--surface-2);}
.quick button:active,.quick a:active{transform:scale(.96);}
.quick svg{width:20px;height:20px;stroke-width:1.6;}

/* horizontal carousel — Airbnb card */
/* scroll-padding matters here. These scrollers bleed to the screen edge with
   a negative margin and pad the gutter back, but scroll-snap-align:start
   aligns to the *scrollport* edge — which is 24px further left than the
   content. Without this the first card comes to rest under the edge of the
   screen, out of line with everything above it. Most obvious on .carousel,
   because mandatory snapping has to land somewhere. */
.carousel{
  display:flex;gap:12px;overflow-x:auto;margin:0 -24px;padding:0 24px 6px;
  scroll-snap-type:x mandatory;scroll-padding-left:24px;
}
.ccard{width:158px;flex:none;scroll-snap-align:start;}
.ccard .ph{width:158px;height:158px;border-radius:var(--r-md);}
.ccard__t{font-size:14px;font-weight:500;margin-top:9px;letter-spacing:-.012em;line-height:1.3;}
.ccard__s{font-size:13.5px;color:var(--ink-2);margin-top:2px;}

.update p{margin:0;font-size:15px;line-height:1.5;letter-spacing:-.01em;}

/* ============================================================
   NOTIFICATION NUDGE
   The only place in the app that asks for notifications. It hides
   itself the moment it has nothing to ask for — see initPush().
   ============================================================ */
.nudge{
  display:flex;align-items:center;gap:14px;width:100%;text-align:left;
  background:var(--surface);border-radius:var(--r-lg);padding:16px 18px;
  box-shadow:var(--elev-sm);transition:transform .12s;
}
.nudge:active{transform:scale(.98);}
.nudge__ic{
  flex:none;width:38px;height:38px;border-radius:var(--r-full);
  background:var(--accent);color:#fff;
  display:flex;align-items:center;justify-content:center;
}
.nudge__ic svg{width:19px;height:19px;stroke-width:1.9;}
.nudge__t{display:block;font-size:15.5px;font-weight:600;letter-spacing:-.014em;}
.nudge__s{display:block;font-size:13.5px;color:var(--ink-2);margin-top:3px;line-height:1.4;}
.nudge__how{
  background:var(--surface);border-radius:var(--r-lg);
  padding:16px 18px;margin-top:10px;box-shadow:var(--elev-sm);
}
.nudge__how ol{margin:0;padding-left:20px;}
.nudge__how li{font-size:14.5px;line-height:1.55;letter-spacing:-.008em;}
.nudge__how li + li{margin-top:8px;}

/* ============================================================
   PRICES
   ============================================================ */
.price{
  display:flex;align-items:center;gap:14px;width:100%;text-align:left;
  padding:16px 0;position:relative;transition:opacity .15s;
}
.price + .price::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:var(--hair);}
.price:active{opacity:.55;}
.price__amt{margin-left:auto;font-size:16.5px;font-weight:600;font-variant-numeric:tabular-nums;}
.grouphd{font-size:13px;font-weight:600;color:var(--ink-2);letter-spacing:0;margin:26px 0 2px;}

/* ============================================================
   GALLERY
   ============================================================ */
.mosaic{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.mosaic .ph{aspect-ratio:1;border-radius:var(--r-md);}
.mosaic .ph:first-child{grid-column:span 2;aspect-ratio:16/11;border-radius:var(--r-lg);}

/* rating + reviews — the score, then example review cards, read-only.
   Nothing is ever written or stored here; Google remains the source. */
.rating{display:flex;align-items:center;gap:16px;margin:-2px 0 18px;}
.rating__n{font-size:44px;font-weight:700;letter-spacing:-.045em;line-height:1;font-variant-numeric:tabular-nums;}
.stars{font-size:14px;letter-spacing:.14em;color:var(--ink);line-height:1;}
.revs{display:flex;gap:12px;overflow-x:auto;margin:0 -24px 18px;padding:2px 24px 6px;scroll-snap-type:x proximity;scroll-padding-left:24px;}
.rev{
  width:246px;flex:none;scroll-snap-align:start;background:var(--surface);
  border-radius:var(--r-lg);padding:18px;box-shadow:var(--elev);
  display:flex;flex-direction:column;
}
.rev__s{font-size:12px;letter-spacing:.14em;color:var(--ink);margin-bottom:9px;}
/* Clamped, not shortened. Google's own listing truncates with "… More" and
   this mirrors it — editing a review's words would be a different thing
   entirely. Without the clamp, one long review sets the height of all three. */
.rev__q{
  font-size:14.5px;line-height:1.5;letter-spacing:-.01em;margin:0 0 14px;flex:1;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:7;overflow:hidden;
}
.rev__m{display:flex;align-items:center;gap:9px;}
.rev__av{
  width:26px;height:26px;border-radius:50%;flex:none;background:var(--surface-3);
  display:grid;place-items:center;font-size:11.5px;font-weight:600;color:var(--ink-2);
}
.rev__n{font-size:12.5px;color:var(--ink-2);line-height:1.3;}
.rev__src{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--ink-3);margin-top:10px;}
/* the Google mark is the one piece of brand colour in the app — it earns it by
   being the thing people recognise before they read the label */
.gmark{width:17px;height:17px;flex:none;}

/* ============================================================
   OWNER
   ============================================================ */
.stepper{display:flex;align-items:center;justify-content:center;gap:22px;}
.stepper button{
  width:48px;height:48px;border-radius:50%;background:var(--surface-2);
  display:grid;place-items:center;font-size:23px;font-weight:400;
  transition:transform .12s var(--ease),background .2s;
}
.stepper button:hover{background:var(--surface-3);}
.stepper button:active{transform:scale(.9);}
.stepper .n{font-size:42px;font-weight:600;letter-spacing:-.04em;min-width:50px;text-align:center;font-variant-numeric:tabular-nums;}

textarea{
  width:100%;padding:15px;border-radius:var(--r-md);resize:none;border:0;
  background:var(--surface);color:var(--ink);font:inherit;font-size:15px;line-height:1.5;
}
textarea::placeholder,input::placeholder{color:var(--ink-3);}
textarea:focus{outline:2px solid var(--ink);outline-offset:0;}
.check{display:flex;align-items:center;gap:12px;padding:16px 0;font-size:14.5px;width:100%;text-align:left;}
.box{width:22px;height:22px;border-radius:6px;flex:none;background:var(--surface-2);display:grid;place-items:center;color:var(--on-btn);transition:background .2s;}
.box.on{background:var(--btn);}
.box svg{width:12px;height:12px;opacity:0;transition:opacity .18s;}
.box.on svg{opacity:1;}

/* made-by footer — deliberately quiet, per the proposal */
.madeby{text-align:center;padding:6px 0 4px;}
.madeby__mark{
  width:38px;height:38px;border-radius:10px;margin:0 auto 12px;
  background:var(--surface-2);display:grid;place-items:center;
  font-size:11px;font-weight:700;letter-spacing:.02em;color:var(--ink-2);
}
.madeby__t{margin:0;font-size:13.5px;color:var(--ink-2);}
.madeby__t b{color:var(--ink);font-weight:600;}
.madeby__link{
  display:inline-flex;align-items:center;gap:5px;margin-top:12px;
  padding:9px 15px;border-radius:var(--r-full);background:var(--surface);
  font-size:13.5px;font-weight:500;color:var(--ink);
  box-shadow:var(--elev-sm);
  transition:background .2s,transform .12s var(--ease);
}
.madeby__link:hover{background:var(--surface-2);}
.madeby__link:active{transform:scale(.97);}

.toast{
  position:absolute;left:24px;right:24px;bottom:calc(env(safe-area-inset-bottom,0px) + 88px);z-index:70;
  padding:15px 17px;border-radius:var(--r-md);background:var(--ink);color:var(--bg);
  font-size:14px;font-weight:500;transform:translateY(20px);opacity:0;pointer-events:none;
  transition:all .35s var(--ease);box-shadow:var(--shadow);
}
.toast.on{transform:none;opacity:1;}

/* ============================================================
   BRAND ACCENT LAYER  —  added 12 Aug 2026
   The monochrome system underneath is unchanged. Two colours only:
     BLUE  #1B34F0  — anything actionable, or anything that is "yours"
     NEON  #CCF94A  — the single thing on a screen that should be seen first
   Everything else stays white / grey / near-black, and the photography
   is still the loudest thing in the app.

   The prototype carried this layer from a wider design system that also
   covered a marketing site and a fuller dashboard. Rules for elements that
   exist on neither of these two pages have been dropped.
   ============================================================ */
/* --accent is the FILL (white always sits on it, so it stays deep).
   --accent-tx is the same blue as TEXT on the page background, and has to
   lighten in dark mode or it fails contrast. Never swap the two. */
html[data-theme="light"]{
  --accent:#1B34F0; --accent-tx:#1B34F0;
  --accent-soft:rgba(27,52,240,.085); --accent-line:rgba(27,52,240,.22);
  --neon:#CCF94A; --neon-ink:#141B04;
}
html[data-theme="dark"]{
  --accent:#2A44FF; --accent-tx:#8DA0FF;
  --accent-soft:rgba(96,121,255,.15); --accent-line:rgba(96,121,255,.3);
  --neon:#CCF94A; --neon-ink:#141B04;
}
::selection{background:var(--accent);color:#fff;}
::selection{background:var(--accent);color:#fff;}

/* ---- actions ------------------------------------------------ */
.btn{background:var(--accent);color:#fff;}
.btn:hover{opacity:.9;}
.btn--soft{background:var(--surface-2);color:var(--ink);}

/* ---- forms + switches --------------------------------------- */
.sw.on{background:var(--accent);}
.box.on{background:var(--accent);color:#fff;}
textarea:focus,input:focus{outline-color:var(--accent);}

/* ---- customer app ------------------------------------------- */
.tabbar button.on{color:var(--accent-tx);}
.busy__fill{background:var(--accent);}
.quick svg{color:var(--accent-tx);}
.rating__n{color:var(--accent-tx);}
.madeby__mark{background:var(--accent);color:#fff;}
.hero__in h1{font-weight:800;}
.hd{font-weight:700;}

/* ---- owner dashboard ---------------------------------------- */
.stepper .n{color:var(--accent-tx);}
.hourrow__c input[type="checkbox"]{accent-color:var(--accent);}
.quote{border-left-color:var(--accent);}


/* ============================================================
   DASHBOARD FORMS
   Everything the owner edits. Sized for a thumb, on a phone, in a
   shop — which is why the reorder controls are up/down buttons and
   not drag handles.
   ============================================================ */
input[type="text"],input[type="password"],input[type="number"],
input[type="url"],input[type="date"],input[type="time"],input[type="file"],select{
  width:100%;padding:13px 15px;border-radius:var(--r-md);border:0;
  background:var(--surface-2);color:var(--ink);font:inherit;font-size:15px;
  -webkit-appearance:none;appearance:none;
}
/* Cards are already --surface, so a field on one needs the next step up
   or it reads as a label with no box around it. */
.card input,.card select,.card textarea{background:var(--surface-2);}
.card input:focus,.card select:focus{background:var(--surface);}
input[type="file"]{padding:11px 15px;font-size:14px;}
select{background-image:none;}
input:focus,select:focus{outline:2px solid var(--ink);outline-offset:0;}

.field{margin-bottom:10px;}
.field label{display:block;font-size:12.5px;font-weight:600;color:var(--ink-2);margin:0 0 6px 2px;}
.field--pair{display:flex;gap:10px;}
.field--pair > *{flex:1;min-width:0;}

.card{
  background:var(--surface);border-radius:var(--r-lg);padding:16px;
  box-shadow:var(--elev-sm);margin-bottom:12px;
}
.card__hd{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
.card__t{font-size:15.5px;font-weight:600;letter-spacing:-.012em;}
.card__s{font-size:13px;color:var(--ink-2);margin-top:2px;line-height:1.45;}
.card__amt{margin-left:auto;font-size:16px;font-weight:600;font-variant-numeric:tabular-nums;}

.tools{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px;}
.tool{
  padding:9px 14px;border-radius:var(--r-full);background:var(--surface-2);
  font-size:13.5px;font-weight:600;color:var(--ink);
  transition:transform .12s var(--ease),opacity .2s;
}
.tool:active{transform:scale(.95);}
.tool--danger{color:var(--danger,#C4302B);}
.tool--go{margin-left:auto;}

.btn--sm{padding:12px;font-size:14.5px;}

/* a sub-screen of the dashboard, reached from a row on the front page */
.subhd{display:flex;align-items:center;gap:12px;margin:0 0 4px;}
.back{
  width:36px;height:36px;border-radius:50%;background:var(--surface-2);
  display:grid;place-items:center;font-size:19px;line-height:1;flex:none;
}
.back:active{transform:scale(.92);}

/* Seven of these have to fit a 375px phone without the "Shut" label
   falling off the end, so every part of the row is allowed to shrink. */
.hourrow{display:flex;align-items:center;gap:8px;padding:12px 0;position:relative;}
.hourrow + .hourrow::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:var(--hair);}
.hourrow__d{width:58px;flex:none;font-size:14px;font-weight:500;}
.hourrow input[type="time"]{padding:10px 8px;font-size:13.5px;min-width:0;flex:1;}
.hourrow__c{display:flex;align-items:center;gap:5px;font-size:12.5px;color:var(--ink-2);flex:none;}
.hourrow__c input[type="checkbox"]{width:18px;height:18px;flex:none;accent-color:var(--btn);}

.thumbrow{display:flex;align-items:center;gap:12px;}
.thumbrow .ph{width:64px;height:64px;border-radius:var(--r-md);flex:none;}

.note{
  background:var(--surface-2);border-radius:var(--r-md);padding:13px 15px;
  font-size:13px;line-height:1.55;color:var(--ink-2);margin:14px 0;
}
.quote{
  background:var(--surface);border-radius:var(--r-lg);padding:18px;
  box-shadow:var(--elev-sm);font-size:15.5px;line-height:1.5;
  border-left:3px solid var(--btn);
}

/* the login page stands alone — no tab bar, no app chrome */
.signin{max-width:380px;margin:0 auto;padding-top:8vh;}
.signin h1{font-size:26px;font-weight:700;letter-spacing:-.03em;margin:0 0 6px;}
.err{
  background:var(--surface-2);border-radius:var(--r-md);padding:13px 15px;
  font-size:13.5px;line-height:1.5;margin-bottom:14px;
  border-left:3px solid var(--danger,#C4302B);
}
