/* Beach Lodge — shared app styling.
   Palette tokens are injected at runtime by /static/theme-init.js (the same
   shim the main ERP uses), so these values are fallbacks that match it 1:1 and
   keep server-rendered pages correct before the script runs.

   A "motion & depth" layer lives at the bottom of this file: entrance cascade,
   hover lift/glow, a drifting aurora backdrop, and richer focus states. It is
   transform/opacity-only (GPU friendly) and fully disabled under
   prefers-reduced-motion. No markup changes were needed. */
:root{
  --bg:#0B1120; --surface:#1E293B; --card:#1E293B; --card2:#334155;
  --border:#334155; --border2:#475569; --border-strong:#475569;
  --text:#F8FAFC; --sub:#cbd5e1; --muted:#94A3B8;
  --text-sub:#cbd5e1; --surface-raised:#334155; --text-muted:#94A3B8;
  --accent:#00E5FF; --accent-soft:rgba(0,229,255,.14);
  --blue:#38bdf8; --green:#22c55e; --danger:#f87171; --negative:#f87171;
  --warn:#f59e0b; --warning:#f59e0b; --purple:#a855f7; --teal:#2dd4bf;
  --sans:'Outfit',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  --r:12px; --r-lg:16px;
  --ease:cubic-bezier(.16,1,.3,1);
  --shadow:0 1px 2px rgba(0,0,0,.25);
  --shadow-lift:0 14px 34px -16px rgba(0,0,0,.65);
}
html[data-theme="light"], body[data-theme="light"], body.light{
  --bg:#ffffff; --surface:#f8fafc; --card:#f8fafc; --card2:#e2e8f0;
  --border:#e2e8f0; --border2:#cbd5e1; --border-strong:#cbd5e1;
  --text:#0f172a; --sub:#334155; --muted:#64748b;
  --text-sub:#334155; --surface-raised:#e2e8f0; --text-muted:#64748b;
  --accent:#00B8D4; --accent-soft:rgba(0,184,212,.12);
  --blue:#0284c7; --green:#15803d; --danger:#dc2626; --negative:#dc2626;
  --warn:#b45309; --warning:#b45309;
  --shadow:0 1px 2px rgba(15,23,42,.06);
  --shadow-lift:0 14px 30px -18px rgba(15,23,42,.28);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;}
body{
  font-family:var(--sans); background:var(--bg); color:var(--text);
  min-height:100vh; font-size:14px; -webkit-font-smoothing:antialiased;
  position:relative;
}
a{color:var(--blue);text-decoration:none;transition:color .15s var(--ease);}
a:hover{text-decoration:underline;}
::selection{background:color-mix(in srgb,var(--accent) 28%,transparent);color:var(--text);}

/* Page container — same as the main ERP */
.content{
  max-width:1300px; margin:0 auto; padding:28px 24px;
  display:flex; flex-direction:column; gap:20px;
}

h1{font-size:24px;font-weight:800;letter-spacing:-.5px;}
h2{font-size:18px;font-weight:800;}
.pagehead{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:14px;}
.pagehead h1{font-size:24px;font-weight:800;letter-spacing:-.5px;}
.sub{color:var(--muted);font-size:13px;margin-top:3px;}
.muted{color:var(--muted);}
.coral{color:var(--danger);}

/* Cards */
.card{
  background:var(--card); border:1px solid var(--border);
  border-radius:var(--r-lg); padding:20px;
  box-shadow:var(--shadow);
  transition:border-color .22s var(--ease), box-shadow .22s var(--ease), transform .22s var(--ease);
}
.card > h2{margin-bottom:6px;}
.card:hover{
  border-color:color-mix(in srgb,var(--accent) 26%,var(--border));
  box-shadow:var(--shadow-lift), 0 0 0 1px color-mix(in srgb,var(--accent) 10%,transparent);
}

/* Grids & stat tiles */
.grid{display:grid;gap:16px;}
.grid.cards,.cards{grid-template-columns:repeat(auto-fit,minmax(190px,1fr));}
.card.stat{display:flex;flex-direction:column;gap:6px;padding:18px 20px;position:relative;overflow:hidden;}
.card.stat::before{
  content:"";position:absolute;left:0;top:0;height:3px;width:100%;
  background:linear-gradient(90deg,var(--accent),var(--teal));
  transform:scaleX(0);transform-origin:left;transition:transform .35s var(--ease);
}
.card.stat:hover{transform:translateY(-3px);
  border-color:color-mix(in srgb,var(--accent) 32%,var(--border));}
.card.stat:hover::before{transform:scaleX(1);}
.stat .k{font-size:11px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:var(--muted);}
.stat .v{font-family:var(--mono);font-size:26px;font-weight:700;letter-spacing:-.5px;color:var(--text);transition:text-shadow .3s var(--ease);}
.card.stat:hover .v{text-shadow:0 0 22px color-mix(in srgb,var(--accent) 45%,transparent);}
.stat .v.coral{color:var(--danger);}
.card.stat:hover .v.coral{text-shadow:0 0 22px color-mix(in srgb,var(--danger) 45%,transparent);}

/* Tables */
table{width:100%;border-collapse:collapse;}
thead{background:var(--card2);}
th{
  text-align:left;font-size:10px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;color:var(--muted);padding:12px 14px;
}
td{padding:12px 14px;border-top:1px solid var(--border);color:var(--sub);font-size:13px;transition:background .15s var(--ease);}
tbody tr td{box-shadow:inset 0 0 0 0 var(--accent);transition:background .15s var(--ease),box-shadow .15s var(--ease);}
tbody tr:hover td{background:color-mix(in srgb,var(--accent) 7%,transparent);}
tbody tr:hover td:first-child{box-shadow:inset 3px 0 0 0 var(--accent);}
td strong{color:var(--text);font-weight:700;}
.right{text-align:right;}
th.right{text-align:right;}
.nowrap{white-space:nowrap;}
td.right,.stat .v,.purchase-total-val{font-family:var(--mono);}
.empty{text-align:center;color:var(--muted);padding:28px;font-size:13px;}

/* Badges */
.pill{
  display:inline-block;padding:3px 10px;border-radius:999px;
  font-size:11px;font-weight:700;letter-spacing:.3px;
  background:var(--accent-soft);color:var(--accent);
  transition:transform .15s var(--ease);
}
.pill.green{color:var(--green);background:color-mix(in srgb,var(--green) 16%,transparent);}
.pill.coral{color:var(--danger);background:color-mix(in srgb,var(--danger) 16%,transparent);}
.pill.amber{color:var(--warn);background:color-mix(in srgb,var(--warn) 18%,transparent);}
.pill.blue{color:var(--blue);background:color-mix(in srgb,var(--blue) 16%,transparent);}
.pill.grey{color:var(--muted);background:color-mix(in srgb,var(--muted) 16%,transparent);}

/* Forms */
.row{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:14px;}
label{
  display:block;font-size:11px;font-weight:700;letter-spacing:1px;
  text-transform:uppercase;color:var(--muted);margin:10px 0 6px;
}
input,select,textarea{
  width:100%;background:var(--card2);border:1px solid var(--border2);
  border-radius:10px;padding:10px 12px;color:var(--text);
  font-family:var(--sans);font-size:14px;outline:none;
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease);
}
input:focus,select:focus,textarea:focus{
  border-color:color-mix(in srgb,var(--accent) 60%,var(--border2));
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 18%,transparent);
}
input::placeholder{color:var(--muted);}

/* Buttons */
.btn{
  display:inline-flex;align-items:center;gap:7px;
  padding:10px 16px;border-radius:var(--r);
  font-family:var(--sans);font-size:13px;font-weight:700;
  cursor:pointer;border:none;white-space:nowrap;text-decoration:none;
  background:linear-gradient(135deg,var(--green),var(--accent));color:#021a10;
  position:relative;overflow:hidden;
  transition:filter .18s var(--ease),transform .18s var(--ease),box-shadow .22s var(--ease),border-color .18s,color .18s;
}
.btn::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(120deg,transparent 28%,rgba(255,255,255,.42),transparent 72%);
  transform:translateX(-130%);transition:transform .6s var(--ease);pointer-events:none;
}
.btn:hover{filter:brightness(1.08);transform:translateY(-1px);text-decoration:none;
  box-shadow:0 8px 22px -8px color-mix(in srgb,var(--accent) 65%,transparent);}
.btn:hover::after{transform:translateX(130%);}
.btn:active{transform:translateY(0) scale(.985);}
.btn.ghost{
  background:transparent;border:1px solid var(--border2);color:var(--sub);
}
.btn.ghost::after{display:none;}
.btn.ghost:hover{border-color:var(--accent);color:var(--text);filter:none;transform:translateY(-1px);box-shadow:none;}
/* The destructive / outward-facing button: cancel a booking, check a guest out
   still owing, hand money back. Seven call sites across the app already ask for
   `btn coral` and none of them got it — the bare `.coral` rule further up sets
   only `color`, at the same specificity as `.btn` but earlier in the file, so
   `.btn`'s own colour won and every one of them rendered as the ordinary green
   confirm button. Naming the pair here is what makes the class mean what its
   call sites have always said. */
.btn.coral{
  background:linear-gradient(135deg,var(--danger),color-mix(in srgb,var(--danger) 72%,#000));
  color:#fff;
}
.btn.coral:hover{box-shadow:0 8px 22px -8px color-mix(in srgb,var(--danger) 65%,transparent);}
button.btn{font-family:var(--sans);}

/* Auth / flash messaging */
.flash,.err{
  border-radius:10px;padding:11px 14px;font-size:13px;margin-bottom:14px;
  animation:flashIn .4s var(--ease) both;
}
.err{background:color-mix(in srgb,var(--danger) 14%,transparent);color:var(--danger);
  border:1px solid color-mix(in srgb,var(--danger) 35%,transparent);}
.flash{background:var(--accent-soft);color:var(--accent);}

::-webkit-scrollbar{width:5px;height:5px;}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:4px;transition:background .2s;}
::-webkit-scrollbar-thumb:hover{background:var(--accent);}

@media(max-width:640px){
  .content{padding:20px 14px;}
  .pagehead{align-items:flex-start;}
}

/* Boosted-navigation progress bar */
#boost-bar{position:fixed;top:0;left:0;height:2px;width:0;opacity:0;
  background:var(--accent);box-shadow:0 0 10px var(--accent),0 0 4px var(--accent);
  z-index:99999;pointer-events:none;}

/* ============================================================
   MOTION & DEPTH LAYER
   Transform/opacity only. Fully disabled under reduced-motion.
   ============================================================ */

/* Living aurora backdrop — sits behind all content, drifts slowly. */
body::before{
  content:"";position:fixed;inset:-25%;z-index:-1;pointer-events:none;
  background:
    radial-gradient(circle at 18% 16%, color-mix(in srgb,var(--accent) 13%,transparent), transparent 42%),
    radial-gradient(circle at 82% 22%, color-mix(in srgb,var(--purple) 10%,transparent), transparent 44%),
    radial-gradient(circle at 72% 88%, color-mix(in srgb,var(--teal) 11%,transparent), transparent 48%);
  animation:auroraDrift 32s ease-in-out infinite alternate;
  will-change:transform;
}
html[data-theme="light"] body::before, body.light::before{opacity:.55;}

@keyframes auroraDrift{
  0%  {transform:translate3d(-2%,-1%,0) scale(1.05) rotate(0deg);}
  50% {transform:translate3d(2%,2%,0)   scale(1.12) rotate(1.5deg);}
  100%{transform:translate3d(-1%,1%,0)  scale(1.06) rotate(-1.5deg);}
}

/* Entrance cascade — each top-level section eases up on load/navigation. */
@keyframes fadeInUp{from{opacity:0;transform:translateY(12px);}to{opacity:1;transform:none;}}
@keyframes flashIn{from{opacity:0;transform:translateY(-6px);}to{opacity:1;transform:none;}}

.content > *{animation:fadeInUp .5s var(--ease) both;}
.content > *:nth-child(1){animation-delay:.02s;}
.content > *:nth-child(2){animation-delay:.07s;}
.content > *:nth-child(3){animation-delay:.12s;}
.content > *:nth-child(4){animation-delay:.17s;}
.content > *:nth-child(5){animation-delay:.22s;}
.content > *:nth-child(6){animation-delay:.27s;}
.content > *:nth-child(n+7){animation-delay:.30s;}
/* Floating pieces show and hide themselves with their own opacity/transform. The cascade's `both` fill would pin
   them at its end state (opacity 1, transform none) for good — a toast that never fades and lands off-centre. */
.content > [class*="toast"],.content > .modal-bg{animation:none;}

/* ── Page switching ──────────────────────────────────────────────────────────
   Moving between pages used to show a blank page that then assembled itself section by section. Now:
   • the browser keeps the old page on screen until the new one is ready and cross-fades the two (cross-document
     view transitions; Chrome / Edge — other browsers simply switch), with the menu bar held perfectly still;
   • a page reached from another page of the app (html.az-nav, set in the head before first paint) is shown at
     once — the section-by-section entrance is kept for the first page of a visit;
   • a slim bar runs along the top while the next page loads (page-progress.js). */
@view-transition{navigation:auto;}
.app-nav{view-transition-name:app-nav;}
::view-transition-group(app-nav){animation:none;}
::view-transition-old(root),::view-transition-new(root){animation-duration:.2s;animation-timing-function:ease;}
html.az-nav .content > *{animation:none;}

.page-progress{position:fixed;top:0;left:0;right:0;height:3px;z-index:2147483000;pointer-events:none;
  opacity:0;transition:opacity .25s ease;}
.page-progress.on{opacity:1;}
.page-progress .bar{height:100%;width:100%;transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,var(--accent),var(--teal,var(--accent)));
  box-shadow:0 0 10px color-mix(in srgb,var(--accent) 60%,transparent),0 0 3px var(--accent);
  transition:transform .2s ease;}
html[dir="rtl"] .page-progress .bar{transform-origin:right center;}
@media print{.page-progress{display:none!important;}}

@media (prefers-reduced-motion: reduce){
  @view-transition{navigation:none;}
  html{scroll-behavior:auto;}
  body::before{animation:none;}
  .content > *{animation:none;}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important;
  }
}