:root{
  /* Palette: black, ivory, gold, with a serif display face. */
  --paper:#f7f5f0;--card:#fff;--card-2:#eeeae0;--ink:#12110e;--ink-soft:#2b2924;--line:#d6cfc0;
  --label:#12110e;--btn-fg:#fff;--badge-fg:#fff;
  --svc-ferry:#7fa3b8;--svc-ferry-bg:#f2f7fa;--svc-ferry-ink:#41718c;
  --svc-salon:#c49bb0;--svc-salon-bg:#faf3f6;--svc-salon-ink:#9c6480;
  --svc-tiki:#c2a86a;--svc-tiki-bg:#faf6ec;--svc-tiki-ink:#8a6d2c;
  --noir:#14130f;--noir-deep:#0a0a08;--gold:#b08d3f;--gold-soft:#f6f0e2;--gold-deep:#8a6d2c;--gold-ink:#7d6227;
  --sage:#4a6b52;--sage-soft:#eef1ea;--danger:#8f3123;--radius:12px;--radius-sm:8px;
  --free-bg:#e9f4ec;--free-line:#b6d9c1;--free-ink:#3f6f50;   /* available time slots */
  --shadow:0 1px 2px rgba(18,17,14,.06), 0 1px 0 var(--line);
}

/* Dark palette, shared by the system setting and the manual choice. */
:root[data-theme="dark"]{
    --paper:#0e0d0b;--card:#161512;--card-2:#221f1a;--ink:#f3f0e8;--ink-soft:#b9b3a6;
    --line:#332f27;--label:#f3f0e8;
    --noir:#f0ece2;--noir-deep:#f7f5f0;--btn-fg:#12110e;--badge-fg:#12110e;
    --gold:#c9a55a;--gold-soft:#2a2317;--gold-deep:#d9b96e;--gold-ink:#d9b96e;
    --sage:#7fae8c;--sage-soft:#1c2a20;--danger:#e07a68;
    --free-bg:#152219;--free-line:#2e4a37;--free-ink:#83c79a;   /* available time slots */
    --svc-ferry:#4d7f9c;--svc-ferry-bg:#131b21;--svc-ferry-ink:#8fbdd6;
    --svc-salon:#a5738b;--svc-salon-bg:#1f151a;--svc-salon-ink:#d7a4bc;
    --svc-tiki:#a8874a;--svc-tiki-bg:#1e1a12;--svc-tiki-ink:#d8b871;
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 1px 0 var(--line);
}

/* Follow the system unless the person has chosen for themselves. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#0e0d0b;--card:#161512;--card-2:#221f1a;--ink:#f3f0e8;--ink-soft:#b9b3a6;
    --line:#332f27;--label:#f3f0e8;
    --noir:#f0ece2;--noir-deep:#f7f5f0;--btn-fg:#12110e;--badge-fg:#12110e;
    --gold:#c9a55a;--gold-soft:#2a2317;--gold-deep:#d9b96e;--gold-ink:#d9b96e;
    --sage:#7fae8c;--sage-soft:#1c2a20;--danger:#e07a68;
    --free-bg:#152219;--free-line:#2e4a37;--free-ink:#83c79a;   /* available time slots */
    --svc-ferry:#4d7f9c;--svc-ferry-bg:#131b21;--svc-ferry-ink:#8fbdd6;
    --svc-salon:#a5738b;--svc-salon-bg:#1f151a;--svc-salon-ink:#d7a4bc;
    --svc-tiki:#a8874a;--svc-tiki-bg:#1e1a12;--svc-tiki-ink:#d8b871;
    --shadow:0 1px 2px rgba(0,0,0,.5), 0 1px 0 var(--line);
  }
}
*{box-sizing:border-box}
/* iOS turns things that look like times or dates into blue links; keep them as text. */
a[x-apple-data-detectors],
a[x-apple-data-detectors] *{color:inherit!important;text-decoration:none!important;
  font-size:inherit!important;font-family:inherit!important;font-weight:inherit!important;
  pointer-events:none}
html,body{margin:0;background:var(--paper);color:var(--ink);font-family:'Inter',system-ui,sans-serif;font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:'Roboto',system-ui,sans-serif;font-weight:700;letter-spacing:-.02em;margin:0 0 .3rem;line-height:1.15}
h1{font-size:2.1rem}
h2{font-size:1.35rem}
h3{font-size:1.1rem}
button{font-family:inherit;cursor:pointer}
a{color:var(--noir)}
:focus-visible{outline:1px solid var(--gold);outline-offset:3px}
.hidden{display:none!important}
.eyebrow{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--label);font-weight:700;margin:0 0 .25rem}
.muted{color:var(--ink-soft);font-size:.9rem;font-weight:400}
/* Page intro descriptions: same gap under the title on every page, and no
   added space between description lines (plain <p> otherwise inherits the
   browser's 1em margins, which differed page to page). */
#page > .page-title + .muted{margin-top:.35rem}
#page > .muted{margin-bottom:0}
#page > .muted + .muted{margin-top:0}
/* topbar */
/* ---- app chrome ---- */
.app-shell{min-height:100dvh;display:flex;flex-direction:column}
.appbar{
  position:sticky;top:0;z-index:30;
  display:flex;align-items:center;justify-content:space-between;gap:.75rem;
  padding:calc(env(safe-area-inset-top, 0px) + .7rem) 1.1rem .7rem;
  background:var(--paper);color:var(--ink);border-bottom:1px solid var(--line);
}
.appbar .brandlock{display:inline-flex;align-items:flex-end;gap:.65rem;min-width:0}
/* Header order (full mirror): menu button left, nav in the middle, brand right. */
.appbar .me{order:0}
.appbar .topnav{order:1}
.appbar .brandlock{order:2}
.appbar .barmark{height:30px;width:auto;display:block;flex:0 0 auto}
.appbar .title{font-family:'Roboto',system-ui,sans-serif;font-size:1.5rem;font-weight:700;line-height:1;
  letter-spacing:-.01em;display:block;
  /* Trim the space Roboto leaves under the baseline so the letters line up
     with the foot of the mark rather than floating above it. */
  margin-bottom:-.04em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;color:var(--ink)}
/* Header navigation: shown on wide screens, replaced by bottom tabs on phones. */
.topnav{display:none}
@media (min-width:760px){
  .topnav{display:flex;align-self:stretch;align-items:flex-end;justify-content:flex-start;gap:.2rem;margin-left:1.5rem;flex:1}
  /* Line the menu button up with the bottom of the nav tabs, which pull down
     into the header padding to meet the bottom border. */
  .appbar .me{align-self:flex-end;margin-bottom:calc(-.7rem - 1px)}
  /* On desktop the logo alone reads as the brand; the page title is mobile-only. */
  .appbar .title{display:none}
  /* The tabs reach down to the header's own bottom border, so the active
     underline sits on that line rather than floating above it. */
  .topnav button{background:none;border:none;
    padding:.55rem .85rem calc(.7rem + 1px);
    margin-bottom:calc(-.7rem - 1px);
    font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
    border-bottom:2px solid transparent;white-space:nowrap}
  .topnav button:hover{color:var(--ink)}
  .topnav button.on{color:var(--ink);font-weight:600;border-bottom-color:var(--gold)}
}
/* avatar menu */
.me{position:relative;flex:0 0 auto}
.me>button{background:none;border:none;padding:0;display:inline-flex;border-radius:50%;cursor:pointer}
.hamburger{border:1px solid var(--line);border-radius:var(--radius-sm);padding:.5rem .55rem;
  color:var(--ink);background:none;cursor:pointer}
.hamburger:hover{border-color:var(--gold)}
.hamburger svg{width:27px;height:27px;display:block}
.me>button:hover .avatar{border-color:var(--gold)}
.me-menu{position:absolute;left:0;top:calc(100% + .5rem);min-width:190px;background:var(--card);
  border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 12px 30px -18px rgba(20,19,15,.5);
  padding:.35rem;z-index:40}
.me-menu .who-line{display:flex;align-items:center;gap:.65rem;padding:.65rem .7rem;
  border-bottom:1px solid var(--line);margin-bottom:.35rem}
.me-menu .who-line .who-text{display:flex;flex-direction:column;min-width:0}
.me-menu .who-line strong{font-size:.9rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.me-menu .who-line .who-text span{font-size:.72rem;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.me-menu{min-width:230px}
.me-menu button{display:block;width:100%;text-align:left;background:none;border:none;padding:.65rem .7rem;
  font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink);border-radius:var(--radius)}
.me-menu button:hover{background:var(--card-2)}
.me-menu button{display:flex;align-items:center;gap:.75rem;width:100%;text-align:left}
.me-menu button svg{width:19px;height:19px;flex:0 0 auto;color:var(--ink-soft)}
.me-menu button.leave svg{color:var(--danger)}
.me-menu button>span:first-of-type{flex:1}
.me-menu .menu-group{padding:.25rem 0;border-bottom:1px solid var(--line)}
.me-menu .menu-group:last-of-type{border-bottom:none}
.me-menu .menu-foot{display:none}
.me-menu .menu-value{font-size:.72rem;letter-spacing:.06em;text-transform:none;color:var(--ink-soft)}
.me-menu button.leave{color:var(--danger)}
.container{width:100%;max-width:940px;margin:0 auto;padding:1.25rem 1.1rem 1.5rem;flex:1}

/* Layout order: on a phone the tabs belong at the bottom, under the thumb.
   On a wide screen they read better directly under the bar. */
.appbar{order:1}
.container{order:2}
.site-footer{order:3}
.tabbar{order:4}

/* bottom tabs */
.tabbar{
  position:sticky;bottom:0;z-index:30;
  display:flex;background:var(--card);border-top:1px solid var(--line);
  padding-bottom:env(safe-area-inset-bottom);
  box-shadow:0 -6px 20px -18px rgba(12,11,9,.6);
}
.tabbar button{
  flex:1;background:none;border:none;padding:.35rem .25rem .4rem;
  display:flex;flex-direction:column;align-items:center;gap:.12rem;
  color:var(--ink-soft);font-size:.6rem;font-weight:500;min-height:48px;text-transform:uppercase;letter-spacing:.14em;
  border-top:2px solid transparent;margin-top:-1px;
}
.tabbar button .ico{font-size:1.15rem;line-height:1.1;display:inline-flex}
.tabbar button .ico svg{width:23px;height:23px;display:block}
.tabbar button.on{color:var(--noir);border-top-color:var(--gold);font-weight:600}
.tabbar button .ico{opacity:.9}
.tabbar button.on .ico{opacity:1;color:var(--gold-deep)}
.tabbar button:active{background:var(--card-2)}

/* Wide screens use the header navigation instead of the bottom tabs. */
@media (min-width:760px){
  .tabbar{display:none}
  .container{order:2}
  .site-footer{order:3}
}
/* panels + forms */
.panel{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:none;padding:1.1rem 1rem;margin-bottom:1rem}
.panel+.panel{margin-top:1.5rem}
label{display:block;font-size:.82rem;font-weight:500;margin-bottom:.3rem}
textarea{width:100%;padding:.6rem .7rem;font-family:inherit;font-size:16px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--paper);color:var(--ink);resize:vertical}
/* A date field carries a calendar mark and sits left, at a width that suits
   its content rather than the column it happens to be in. */
input[type="date"]{
  -webkit-appearance:none;appearance:none;text-align:left;
  max-width:15rem;padding-right:2.4rem;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2357534b' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .7rem center;background-size:18px 18px;
}
input[type="date"]::-webkit-calendar-picker-indicator{
  position:absolute;right:0;width:2.4rem;height:100%;opacity:0;cursor:pointer;
}
input[type="date"]::-webkit-date-and-time-value{text-align:left}

/* Dropdowns get their own chevron so they read as dropdowns everywhere. */
select:not([size]){
  -webkit-appearance:none;appearance:none;padding-right:2.4rem;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2357534b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .7rem center;background-size:18px 18px;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) input[type="date"],
  :root:not([data-theme="light"]) select:not([size]){
    background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b9b3a6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  }
  :root:not([data-theme="light"]) input[type="date"]{
    background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b9b3a6' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] input[type="date"],
:root[data-theme="dark"] select:not([size]){
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b9b3a6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] input[type="date"]{
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b9b3a6' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
}
.field{position:relative}

select[size]{padding:.35rem;height:auto;-webkit-appearance:listbox;appearance:listbox;background-image:none}
select[size] option{padding:.4rem .45rem}
input,select{width:100%;padding:.7rem .75rem;font-family:inherit;font-size:16px;font-weight:500;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--paper);color:var(--ink);transition:border-color .15s ease}
input:focus,select:focus,textarea:focus{border-color:var(--gold)}
.field{margin-bottom:.9rem}
.row{display:flex;gap:.9rem;flex-wrap:wrap}.row>.field{flex:1;min-width:130px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.4rem;padding:.85rem 1.4rem;border:1.5px solid var(--noir);border-radius:var(--radius-sm);background:var(--noir);color:var(--btn-fg);font-weight:600;font-size:.73rem;text-transform:uppercase;letter-spacing:.14em}
.btn:hover{background:var(--noir-deep);border-color:var(--noir-deep)}.btn.block{width:100%}
.btn.ghost{background:transparent;color:var(--noir);border:1.5px solid var(--noir)}.btn.ghost:hover{background:var(--noir);color:var(--btn-fg)}
.btn.gold{background:transparent;color:var(--ink);border:1.5px solid var(--gold)}
a.btn{text-decoration:none}
a.btn.ghost{background:transparent;color:var(--noir)}
a.btn.gold{background:transparent;color:var(--ink)}
a.btn.plain{background:transparent;color:var(--ink)}
@media (max-width:759px){
  /* Mobile top bar: menu left, title centred, logo on the right — like a
     native app. Symmetric 1fr side columns keep the title truly centred; the
     brand lock is flattened so its title and logo drop into their own cells. */
  .appbar{display:grid;grid-template-columns:1fr auto 1fr;grid-template-rows:auto;align-items:center;gap:.5rem}
  .appbar .me{grid-area:1/1;justify-self:start}
  .appbar .brandlock{display:contents}
  .appbar .title{grid-area:1/2;justify-self:center;min-width:0;max-width:100%}
  .appbar .barmark{grid-area:1/3;justify-self:end}
  .me-menu{position:fixed;inset:0 auto 0 0;top:0;left:0;bottom:0;
    width:min(82vw, 320px);max-width:none;min-width:0;
    border-radius:0;border:none;border-right:1px solid var(--line);
    box-shadow:0 0 60px rgba(0,0,0,.45);
    padding:calc(env(safe-area-inset-top, 0px) + 1rem) .9rem calc(env(safe-area-inset-bottom, 0px) + 1rem);
    display:flex;flex-direction:column;gap:.15rem;overflow-y:auto;
    transform:translateX(-100%);transition:transform .2s ease-out;z-index:60}
  .me-menu:not(.hidden){transform:translateX(0)}
  .me-menu.hidden{display:flex;pointer-events:none}
  .me-menu .who-line{padding:.4rem .55rem 1rem;margin-bottom:.6rem}
  .me-menu .who-line .avatar{width:48px;height:48px}
  .me-menu .who-line strong{font-size:1rem}
  .me-menu button{padding:.9rem .6rem;font-size:.82rem}
  .me-menu button.leave{margin-top:0}
  .me-menu .menu-group{padding:.35rem 0}
  .me-menu .menu-foot{display:block;margin-top:auto;padding:1rem .6rem 0;
    font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft)}
  /* A dimmed page behind it, so the panel reads as the thing in front. */
  .menu-scrim{position:fixed;inset:0;background:rgba(8,8,7,.5);
    -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:55}
  .menu-scrim.hidden{display:none}
}

.contact-choice{display:flex;flex-direction:column;gap:.5rem}
.contact-choice .btn{width:100%}.btn.gold:hover{background:var(--gold-soft)}
.btn.danger{background:transparent;color:var(--danger);border:1.5px solid var(--line);padding:.5rem .75rem;font-size:.66rem;letter-spacing:.14em}.btn.danger:hover{background:var(--danger);color:#fff;border-color:var(--danger)}
.btn.plain{background:transparent;color:var(--ink);border:1.5px solid var(--line)}.btn.plain:hover{background:var(--card-2);color:var(--ink)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.alert{padding:.8rem .95rem;border-radius:var(--radius-sm);font-size:.87rem;margin-bottom:1rem;border-left:2px solid}
.alert.err{background:#faf1ef;color:var(--danger);border-color:var(--danger)}
.alert.ok{background:var(--gold-soft);color:var(--ink);border-color:var(--gold)}
.alert.info{background:var(--card-2);color:var(--ink-soft);border-color:var(--line)}
/* auth */
.auth-wrap{min-height:100vh;display:grid;place-items:center;padding:1.5rem}
.auth-card{width:100%;max-width:380px}.auth-card .hero{text-align:center;margin-bottom:1.5rem}.auth-card .hero .mark{display:block;margin:0 auto .6rem;width:132px;height:auto}
.switcher{text-align:center;margin-top:1rem;font-size:.88rem;color:var(--ink-soft)}
.switcher button{background:none;border:none;color:var(--noir);font-weight:600;padding:0}
/* tickets */
.legend{display:flex;gap:1rem;flex-wrap:wrap;font-size:.78rem;color:var(--ink-soft);margin:1rem 0}
.legend span{display:inline-flex;align-items:center;gap:.35rem}
.swatch{width:13px;height:13px;display:inline-block;border:1px solid var(--line);background:var(--card)}
.swatch.mine{border-color:var(--gold);background:var(--gold-soft)}
.swatch.taken{background:var(--card-2);border-style:dashed}
.tickets{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:.6rem}
.ticket{position:relative;text-align:left;color:var(--ink);background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:.85rem .9rem .9rem;display:flex;flex-direction:column;gap:.4rem;min-height:96px;transition:border-color .15s ease,background .15s ease}
.ticket .time{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:1.2rem;font-weight:500;letter-spacing:-.01em;line-height:1}
.ticket .stamp{align-self:flex-start;font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft);font-weight:500}
.ticket .sub{font-size:.7rem;color:var(--ink-soft);font-weight:300}
/* Gold is the only accent, so it marks what is yours. Free slots stay quiet. */
.ticket.free{cursor:pointer;background:var(--free-bg);border-color:var(--free-line)}
.ticket.free .stamp{color:var(--free-ink)}
.ticket.free:hover{border-color:var(--free-ink);background:var(--free-bg);box-shadow:inset 2px 0 0 var(--free-ink)}
.ticket.taken{background:var(--card-2);border-style:dashed}
.ticket.taken .time,.ticket.taken .stamp{color:var(--ink-soft)}
.ticket.mine{border-color:var(--gold);background:var(--gold-soft);box-shadow:inset 2px 0 0 var(--gold)}
.ticket.mine .stamp{color:var(--ink)}
.ticket .cancel{align-self:flex-start;background:none;border:none;color:var(--danger);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;padding:0;cursor:pointer;border-bottom:1px solid currentColor}
/* lists */
.list{display:flex;flex-direction:column;gap:.5rem;margin-top:.8rem}
.list-row{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.7rem .85rem;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.list-row .when{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:.9rem}
.row-actions{display:flex;gap:.4rem;flex-shrink:0;align-items:center}
/* The person block takes the free space and is allowed to shrink; long emails
   wrap instead of widening the page. */
.person{display:flex;gap:.6rem;align-items:flex-start;flex:1 1 auto;min-width:0}
.person-text{min-width:0;flex:1 1 auto}
.list-row>span:first-child{min-width:0}
.list-row .who{overflow-wrap:anywhere}
.list-row .who{font-size:.85rem;color:var(--ink-soft)}
.pill{font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;padding:.15rem .5rem;border:1px solid var(--line);border-radius:999px}
.pill.admin{background:var(--gold-soft);color:var(--gold-ink);border-color:var(--gold)}.pill.member{background:var(--card-2);color:var(--ink-soft)}
.empty{text-align:center;padding:1.4rem 1rem;color:var(--ink-soft)}
/* ferry */
.sail{display:flex;align-items:center;gap:.9rem;padding:.9rem 1rem;border:1px solid var(--line);border-radius:var(--radius);background:var(--card);margin-bottom:.55rem}
.sail .time{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:1.2rem;font-weight:500;line-height:1;min-width:4rem}
.sail .route{font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft)}
.sail .seats{font-size:.78rem;color:var(--ink-soft);margin-top:.15rem}
.sail .grow{flex:1;min-width:0}
.sail.gone{opacity:.5}
.panel.departed{opacity:.62}
.panel.departed:hover{opacity:1}
.sail.mine{border-color:var(--gold);background:var(--gold-soft)}
.seatbar{height:3px;background:var(--card-2);margin-top:.4rem;max-width:160px}
.seatbar span{display:block;height:100%;background:var(--gold)}
.state{font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;padding:.2rem .55rem;border:1px solid var(--line);border-radius:999px;white-space:nowrap}
.state.ok{background:var(--gold-soft);color:var(--ink);border-color:var(--gold)}
.state.wait{background:var(--card-2);color:var(--ink-soft)}
.state.full{color:var(--danger);border-color:var(--line)}
/* boarding pass */
.pass{text-align:center}
.receipt{margin-top:.4rem;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.receipt-row{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;
  padding:.65rem .8rem;text-align:left;border-bottom:1px solid var(--line)}
.receipt-row:last-child{border-bottom:none}
.receipt-row span{font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft);flex:0 0 auto}
.receipt-row strong{font-weight:600;text-align:right}
.receipt-row .mono{font-variant-numeric:tabular-nums;letter-spacing:.08em}
.pass .qr{background:#fff;padding:.9rem;display:inline-block;border:1px solid var(--line);margin:.6rem 0}
.pass .qr img,.pass .qr svg{display:block;width:210px;height:210px}
.pass .ref{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;letter-spacing:.18em;font-size:1rem}
.pass .who{font-weight:600;font-size:1rem}
@media print{
  body *{visibility:hidden}
  #printable,#printable *{visibility:visible}
  #printable{position:absolute;left:0;top:0;width:100%;padding:0}
  .no-print{display:none!important}
}
/* boarding: camera stage with the result shown over it */
.scanpanel{padding:1rem}
.scanstage{position:relative;width:100%;aspect-ratio:3/4;max-height:60vh;overflow:hidden;
  background:#000;border-radius:var(--radius);margin-bottom:.9rem}
.scanstage video{width:100%;height:100%;object-fit:cover;display:block}
.scanframe{position:absolute;inset:14% 10%;border:3px solid rgba(255,255,255,.85);
  border-radius:12px;box-shadow:0 0 0 100vmax rgba(0,0,0,.28);pointer-events:none}
.scanresult{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:.6rem;text-align:center;padding:1.2rem;
  color:#fff;opacity:0;visibility:hidden;transition:opacity .12s ease-out}
.scanresult.show{opacity:1;visibility:visible}
.scanresult.ok{background:rgba(30,92,58,.96)}
.scanresult.warn{background:rgba(138,109,44,.96)}
.scanresult.no{background:rgba(143,49,35,.96)}
.scanresult .verdict{font-family:'Roboto',system-ui,sans-serif;font-weight:700;
  font-size:1.9rem;letter-spacing:.02em;line-height:1}
.scanresult .who-name{font-size:1.15rem;font-weight:600}
.scanresult .detail{font-size:.85rem;color:rgba(255,255,255,.9)}
.scanresult .avatar{width:74px;height:74px;border-color:rgba(255,255,255,.6)}
.scantally{display:flex;justify-content:space-between;align-items:center;
  font-size:.8rem;color:var(--ink-soft);margin:.15rem 0 .7rem}
.scantally strong{color:var(--ink);font-size:1.05rem}
.scanpanel details summary::-webkit-details-marker{display:none}

.msg{border:1px solid var(--line);border-radius:var(--radius-sm);margin-bottom:.5rem;background:var(--card)}
.msg summary{padding:.7rem .85rem;cursor:pointer;list-style:none;display:flex;gap:.6rem;align-items:flex-start}
.msg summary::-webkit-details-marker{display:none}
.msg summary::before{content:'▸';color:var(--ink-soft);flex:0 0 auto;margin-top:.1rem}
.msg[open] summary::before{content:'▾'}
.msg .msg-body{padding:0 .85rem .85rem;border-top:1px solid var(--line);margin-top:.2rem;padding-top:.8rem}
.msg code{background:var(--card-2);padding:.05rem .3rem;border-radius:4px;font-size:.92em}

.manifest-table{width:100%;border-collapse:collapse;font-size:.82rem;margin-top:.8rem}
.manifest-table th,.manifest-table td{text-align:left;padding:.45rem .5rem;border-bottom:1px solid var(--line)}
.manifest-table th{font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft)}
/* avatars */
.avatar{border-radius:50%;object-fit:cover;background:var(--card-2);border:1px solid var(--line);flex:0 0 auto;display:block}
.avatar.ph{display:inline-flex;align-items:center;justify-content:center;font-family:'Roboto',system-ui,sans-serif;color:var(--ink-soft);line-height:1}
.avatar-lg{width:96px;height:96px;font-size:2.1rem}
.avatar-sm{width:38px;height:38px;font-size:1rem}
.avatar-xs{width:26px;height:26px;font-size:.75rem}
.photo-row{display:flex;align-items:center;gap:1rem;margin:1rem 0}
.photo-actions{display:flex;gap:.5rem;flex-wrap:wrap}
/* cropper */
.crop-frame{position:relative;width:100%;max-width:280px;aspect-ratio:1/1;margin:0 auto;overflow:hidden;
  background:var(--card-2);border:1px solid var(--line);touch-action:none;cursor:grab;border-radius:50%}
.crop-frame.dragging{cursor:grabbing}
.crop-frame img{position:absolute;transform-origin:0 0;user-select:none;-webkit-user-drag:none;pointer-events:none;max-width:none}
.crop-hint{text-align:center;font-size:.78rem;color:var(--ink-soft);margin:.6rem 0 .2rem}
.crop-zoom{display:flex;align-items:center;gap:.6rem;margin:.5rem 0 .2rem}
.crop-zoom input[type=range]{flex:1;accent-color:var(--gold)}
.crop-zoom span{font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
/* hub home */
.hub-hero{margin-bottom:1.1rem}
/* The header carries the screen name on narrow screens, so the page heading
   beneath it would just say the same thing twice. */
@media (max-width:759px){ h1.page-title{display:none} }
/* compact links to each service, in place of the old cards */
/* Each service carries a soft colour so bookings are told apart at a glance. */
.list-row.svc{border-left:3px solid var(--line);gap:.7rem}
.list-row.svc .svc-mark{display:inline-flex;align-items:flex-start;flex:0 0 auto;padding-top:.15rem}
.list-row.svc>span:nth-child(2){flex:1 1 auto;min-width:0;text-align:left}
.list-row.svc .svc-mark svg{width:18px;height:18px}
.list-row.svc-ferry{border-left-color:var(--svc-ferry);background:var(--svc-ferry-bg)}
.list-row.svc-ferry .svc-mark{color:var(--svc-ferry-ink)}
.list-row.svc-salon{border-left-color:var(--svc-salon);background:var(--svc-salon-bg)}
.list-row.svc-salon .svc-mark{color:var(--svc-salon-ink)}
.list-row.svc-tiki{border-left-color:var(--svc-tiki);background:var(--svc-tiki-bg)}
.list-row.svc-tiki .svc-mark{color:var(--svc-tiki-ink)}

.quick{display:flex;flex-direction:column;gap:.5rem;margin-top:1.5rem}
.quick button{display:flex;align-items:center;gap:.7rem;width:100%;text-align:left;
  background:var(--card);border:1px solid var(--line);padding:.8rem .9rem;color:var(--ink);
  font-size:.85rem;letter-spacing:.02em}
.quick button:hover{border-color:var(--gold);background:var(--gold-soft)}
.quick button svg{width:20px;height:20px;flex:0 0 auto;color:var(--gold-ink)}
@media (min-width:620px){ .quick{flex-direction:row} .quick button{flex:1} }
.hub-hero h1{margin-bottom:.3rem}
.hub-sub{margin:0;font-size:.95rem}
.services{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1rem}
.service{display:block;text-align:left;width:100%;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:none;padding:1.6rem 1.4rem;transition:border-color .15s ease}
.service:hover{border-color:var(--gold)}
.service .icon{font-size:1.5rem;line-height:1;color:var(--gold);display:inline-flex}
.service .icon svg{width:26px;height:26px;display:block}
.service h3{font-family:'Roboto',system-ui,sans-serif;font-size:1.2rem;font-weight:500;letter-spacing:-.01em;margin:.6rem 0 .35rem;color:var(--ink)}
.service p{margin:0;font-size:.88rem;color:var(--ink-soft)}
.service .go{display:inline-block;margin-top:.9rem;font-size:.64rem;font-weight:500;color:var(--gold-ink);text-transform:uppercase;letter-spacing:.18em;border-bottom:1px solid var(--gold);padding-bottom:.2rem}
.service.soon{background:var(--card-2);cursor:default}
.service.soon:hover{border-color:var(--line)}
.service.soon h3{color:var(--ink-soft)}
.tag{display:inline-block;font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;padding:.15rem .5rem;border-radius:999px;background:var(--card-2);color:var(--ink-soft);border:1px solid var(--line)}
.tag.live{background:var(--gold-soft);color:var(--gold-ink);border-color:var(--gold)}
/* modal */
.overlay{position:fixed;inset:0;background:rgba(8,8,7,.62);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;padding:1rem;z-index:50;
  animation:overlay-in .15s ease}
.modal{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 20px 50px -20px rgba(12,11,9,.6);padding:1.25rem;width:100%;max-width:400px;
  animation:modal-in .18s cubic-bezier(.2,.7,.3,1)}
@keyframes overlay-in{from{opacity:0}to{opacity:1}}
@keyframes modal-in{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
.modal h3{font-family:'Roboto',system-ui,sans-serif;font-size:1.15rem;margin:0 0 .4rem}
.modal .when{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:1rem;background:var(--card-2);border-radius:var(--radius);padding:.6rem .7rem;margin:.7rem 0}
.modal textarea{width:100%;font-family:inherit;font-size:16px;padding:.6rem .7rem;border:1px solid var(--line);border-radius:var(--radius);background:var(--paper);color:var(--ink);resize:vertical;min-height:76px}
.modal-actions{display:flex;gap:.5rem;margin-top:1rem}
.modal-actions .btn{flex:1}
.btn.plain{background:transparent;color:var(--ink);border:1.5px solid var(--line)}
.btn.plain:hover{background:var(--card-2)}
/* activity log */
.log{display:flex;flex-direction:column;gap:.4rem;margin-top:.8rem}
.log-row{padding:.55rem .7rem;border:1px solid var(--line);border-radius:var(--radius);background:var(--card)}
.log-row .head{display:flex;justify-content:space-between;gap:.6rem;flex-wrap:wrap}
.log-row .act{font-weight:600;font-size:.87rem}
.log-row .at{font-family:'Roboto',system-ui,sans-serif;font-variant-numeric:tabular-nums;font-size:.72rem;color:var(--ink-soft);white-space:nowrap}
.log-row .det{font-size:.82rem;color:var(--ink-soft);margin-top:.15rem}
.log-row .by{font-size:.75rem;color:var(--ink-soft)}
.tabs{display:flex;gap:.35rem;margin:1rem 0 .25rem;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs button{flex:0 0 auto;white-space:nowrap}
.badge{display:inline-block;min-width:1.15rem;padding:0 .3rem;margin-left:.3rem;border-radius:999px;
  background:var(--gold);color:var(--badge-fg);font-size:.62rem;line-height:1.15rem;text-align:center;font-weight:600}
.tabs button{background:transparent;border:1px solid var(--line);color:var(--ink-soft);padding:.45rem .8rem;border-radius:var(--radius);font-size:.85rem}
.tabs button.on{background:var(--noir);border-color:var(--noir);color:var(--btn-fg);font-weight:600}
.tabs button .badge{background:var(--card-2);color:var(--ink-soft)}
.tabs button.on .badge{background:var(--gold);color:var(--badge-fg)}
.site-footer{margin-top:auto;padding:1.6rem 1.25rem;text-align:center;font-size:.68rem;line-height:1.6;letter-spacing:.06em;color:var(--ink-soft);font-weight:300;border-top:1px solid var(--line);background:var(--paper)}
.auth-wrap .site-footer{border-top:none;padding-top:2.25rem;background:transparent}
.section-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.2rem;gap:1rem}
@media (max-width:560px){
  .container{padding:1.1rem .9rem 2.5rem}
  h1{font-size:1.5rem}
  h2{font-size:1.15rem}

  /* Top bar: one tidy row. The longer name shrinks before the buttons do. */
  .appbar{padding-left:.85rem;padding-right:.85rem}
  .appbar .title{font-size:1.25rem;letter-spacing:-.01em}
  .services{grid-template-columns:1fr;gap:.8rem}

  /* Comfortable thumb targets */
  .btn{min-height:46px;width:100%}
  /* Buttons inside a ferry row sit beside the text, not across it. */
  .sail .btn,.sail .state{width:auto;flex:0 0 auto;white-space:nowrap;min-height:40px}
  .sail{gap:.7rem;padding:.8rem .85rem}
  .sail .time{min-width:3.5rem;font-size:1.1rem}
  .sail .route{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
  .btn.danger{min-height:40px;width:auto;padding:.5rem .8rem}
  .ticket{min-height:78px;padding:.65rem .7rem .7rem}
  .ticket .sub{display:none}          /* "Tap to book" is obvious on a phone */
  .ticket .cancel{min-height:32px;display:inline-flex;align-items:center}
  .tickets{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.55rem}

  /* Keep row layout but let long dates/emails wrap instead of squashing the button.
     Pairs of buttons drop onto their own line rather than being clipped. */
  .list-row{gap:.6rem;padding:.65rem .7rem;flex-wrap:wrap}
  .list-row>span:last-child:not(:first-child){margin-left:auto}
  .list-row .row-actions{width:100%;justify-content:flex-end}
  .list-row>span:first-child{flex:1;min-width:0}
  .list-row .btn.danger,.list-row .btn.ghost{flex:0 0 auto;width:auto;white-space:nowrap;min-height:40px}
  .section-head{flex-wrap:wrap;gap:.3rem}

  .row{gap:.6rem}
  .row>.field{min-width:100%}         /* one field per line, full width */
  .date-strip .field,.field{max-width:100%}
  .legend{gap:.7rem;font-size:.75rem}
  .site-footer{padding:1.35rem 1.1rem;font-size:.64rem}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
