:root{
  --bg:#05070C; --glass:rgba(15,20,29,.72); --glass2:rgba(10,14,21,.62);
  --ink:#EDEFF4; --dim:#8E97A8; --hair:rgba(255,255,255,.08); --hair2:rgba(255,255,255,.14);
  --accent:#6C8CFF; --accent2:#8CA4FF; --err:#FF7A6B; --warn:#FF8A4D; --ok:#5FE3B0;
  --fly:#7FC8FF; --drv:#FF8A4D; --rail:#C69BFF; --stay:#FFD34D; --boat:#FF7AC4; --inspo:#FF6FB5; --points:#4FE08A; --acct:#9AA6BD;
  --font:'Inter',-apple-system,'Segoe UI',sans-serif;
  --disp:'Bricolage Grotesque','Inter',sans-serif;
  --mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --r:16px;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{font-family:var(--font);color:var(--ink);background:var(--bg);font-size:14.5px;line-height:1.5;overflow:hidden}
button,input,textarea,select{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:8px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* hidden until it has been positioned, so it is never seen in the wrong place */
/* The map is covered while it settles rather than faded: putting opacity on
   the map composites the whole thing separately, which is not something to do
   to an element Leaflet is busy transforming. */
.bootcover{position:fixed;inset:0;z-index:11;background:var(--bg);pointer-events:none;transition:opacity .16s ease}
body.mapready .bootcover{opacity:0}
/* something to watch while it settles, rather than a blank rectangle */
.bootspin{position:fixed;inset:0;z-index:12;display:flex;align-items:center;justify-content:center;pointer-events:none;transition:opacity .22s ease}
.bootspin.gone{opacity:0}
body.mapready .bootspin{opacity:0}
.bootspin .ring{width:34px;height:34px;border-radius:50%;border:3px solid rgba(255,255,255,.14);border-top-color:rgba(255,255,255,.62);animation:bootspin .8s linear infinite}
@keyframes bootspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.bootspin .ring{animation:none}}

/* a name that isn't known yet reads as waiting, not as "Guest" */
.acchead.loading{opacity:.75}
/* Where the picker will be: the same box, empty, with one bar shimmering
   inside it. No arrow, because there is nothing yet to drop down. */
/* Opaque, deliberately. A translucent box sits over the map, and the map is
   mostly blue — which tints anything semi-transparent above it. Both this and
   the bar inside it are solid, so nothing beneath can colour them. */
.selwait{display:flex;align-items:center;flex:1;min-width:0;height:34px;padding:0 10px;
  background:#0E121A;border:1px solid rgba(255,255,255,.10);border-radius:8px;pointer-events:none}
/* Named waitbar, not selbar. There is already a .selbar — the multi-select
   toolbar — with a blue border and a blue tint, and it sits later in this file,
   so it won the cascade and drew a blue pill inside the waiting card. */
.waitbar{display:block;height:11px;width:58%;border-radius:4px;background-color:#1A1F2A;
  background-image:linear-gradient(90deg,#1A1F2A,#262C39 50%,#1A1F2A);
  background-size:200% 100%;animation:skelslide 1.1s linear infinite}
@media (prefers-reduced-motion:reduce){.waitbar{animation:none}}
/* covers the text rather than replacing it, so the line keeps its own height */
.skel{color:transparent;border-radius:4px;max-width:104px;
  background:linear-gradient(90deg,rgba(255,255,255,.07),rgba(255,255,255,.16),rgba(255,255,255,.07));
  background-size:200% 100%;animation:skelslide 1.1s linear infinite}
.acname.skel{max-width:74px}
@keyframes skelslide{from{background-position:200% 0}to{background-position:-200% 0}}
#map{position:fixed;inset:0;background:var(--bg)}
/* A 160px-blur inset box-shadow across the whole viewport is one of the most
   expensive things a browser can be asked to composite, and it sits directly
   above the map. A radial gradient produces the same darkening at the edges
   for a fraction of the cost, and can be rasterised once. */
/* The browser's own [hidden] rule is display:none, but any class that sets a
   display beats it — so hiding a .addtrip button by setting `hidden` did
   nothing at all. This makes the attribute mean what it says. */
[hidden]{display:none!important}

/* Where a confirmation or a calendar invite lands. A label wrapping a hidden
   file input, so it works by click, by keyboard and by drag alike. */
/* Shown to anyone signed in who is not on Pro. One line: the fact, then a
   button to press. It is meant to catch the eye, so it carries the same colours
   as the Pro page itself rather than sitting grey among the trip cards. */
.startblock{display:block;width:100%}
.pronote{display:flex;align-items:center;gap:9px;margin:9px 0 12px;padding:8px 9px 8px 11px;
  width:100%;box-sizing:border-box;
  border:1px solid color-mix(in srgb,var(--accent2) 42%,transparent);border-radius:12px;
  background:linear-gradient(100deg,rgba(108,140,255,.22),rgba(127,200,255,.12) 55%,rgba(183,140,255,.18));
  font-size:12.5px;color:var(--ink);cursor:pointer;
  transition:border-color .16s ease,box-shadow .16s ease,transform .16s ease}
.pronote:hover{border-color:var(--accent2);transform:translateY(-1px);
  box-shadow:0 8px 22px -14px var(--accent2)}
.pnico{color:#BFD4FF;line-height:0;flex-shrink:0}
.pntxt{flex:1;min-width:0;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The thing to press, and it looks like one. */
.pncta{flex-shrink:0;border:0;border-radius:8px;padding:5px 11px;cursor:pointer;
  font-family:var(--disp);font-weight:800;font-size:12px;letter-spacing:-.01em;
  background:linear-gradient(135deg,#7FC8FF,#8CA4FF 60%,#B78CFF);color:#070B18}
.pncta:hover{filter:brightness(1.08)}
.pnx{border:0;background:none;color:var(--dim);font-size:12px;line-height:1;
  padding:3px 4px;cursor:pointer;flex-shrink:0;border-radius:6px}
.pnx:hover{color:var(--ink);background:rgba(255,255,255,.1)}
@supports not (color:color-mix(in srgb,red 50%,transparent)){
  .pronote{border-color:rgba(140,164,255,.42)}
}
@media (max-width:420px){
  /* the words give way before the button does */
  .pntxt{font-size:12px}
}
@media (prefers-reduced-motion:reduce){.pronote{transition:none}.pronote:hover{transform:none}}

/* The import screen: a place to drop, a place to paste, one button. */
.impwrap{display:flex;flex-direction:column;gap:10px}
.impwrap .dropzone{margin-top:4px;padding:26px 16px}
.impbox{width:100%;box-sizing:border-box;border:1px solid var(--hair2);border-radius:12px;
  padding:11px 12px;background:rgba(0,0,0,.3);color:var(--ink);
  font-family:var(--font);font-size:12.5px;line-height:1.6;resize:vertical}
.impbox:focus{border-color:var(--accent2);outline:none}
.impwrap .addtrip{margin-top:2px}
.sbbtn.ghost{border-color:transparent;color:var(--dim)}
.sbbtn.ghost:hover{border-color:var(--hair2);color:var(--ink)}
.dropzone{display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center;
  margin-top:14px;padding:20px 16px;cursor:pointer;
  border:1px dashed var(--hair2);border-radius:14px;background:rgba(255,255,255,.02);
  transition:border-color .18s ease,background .18s ease,transform .18s ease}
.dropzone:hover{border-color:var(--accent2);background:rgba(255,255,255,.04)}
.dropzone.over{border-color:var(--accent2);background:rgba(108,140,255,.1);transform:scale(1.01)}
.dzico{color:var(--accent2);line-height:0}
.dztitle{font-weight:700;font-size:13px;color:var(--ink)}
.dzsub{font-size:11.5px;color:var(--dim)}
@media (prefers-reduced-motion:reduce){.dropzone{transition:none}.dropzone.over{transform:none}}

/* A stop pin, lit while its card is hovered. The pin is a div icon rather than
   a line, so it grows and glows in its own colour instead of the glow a leg
   line has behind it. */
.stopmk{transition:transform .18s cubic-bezier(.22,.61,.36,1)}
.stopmk.hl{transform:scale(1.3);z-index:700}
.stopmk.hl>div{border-color:#FFFFFF!important;
  box-shadow:0 0 0 5px rgba(255,211,77,.35),0 0 16px 2px rgba(255,211,77,.55),0 2px 8px rgba(0,0,0,.8)!important}
@media (prefers-reduced-motion:reduce){.stopmk{transition:none}.stopmk.hl{transform:none}}

/* Read by search engines and screen readers, seen by nobody: the wordmark
   carries the same words visually. Not display:none, which would take it out
   of the accessibility tree as well. */
.sronly{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.nojs{max-width:520px;margin:14vh auto;padding:0 24px;color:#C9D2E2;font-family:system-ui,sans-serif;line-height:1.6}
.nojs h2{font-size:26px;margin:0 0 12px}

/* Safari zooms the page when a field smaller than 16px takes focus, which is
   what made the promo box jump. Sixteen pixels on a phone costs nothing and
   stops the zoom. */
@media (max-width:760px){
  /* Marked important because the field rules are class-based and outrank a
     bare element selector — without it every input kept its 12.5px and Safari
     carried on zooming. */
  input,textarea,select{font-size:16px!important}
}
/* A defensive net. An earlier waiting card outlined the Copy link button,
   which is a blue pill — if any cached build still renders that markup, this
   strips the colour out of it rather than leaving a blue bar in a grey card. */
.copyspace.skel,.sbbtn.skel,.sbsel.skel{
  background:rgba(255,255,255,.05)!important;border-color:rgba(255,255,255,.09)!important;
  color:transparent!important;box-shadow:none!important;pointer-events:none}

/* A page with no plan to show: the map drains of colour and a padlock sits
   over it, so it reads as closed rather than as a map that failed to load. */
/* The same imagery as everywhere else, dimmed and drained by a flat layer
   over it rather than by a filter on the tiles. A filter makes the browser
   re-rasterise every tile after decoding it, which is what doubled the time a
   locked page took to appear; a plain overlay costs one composite. */
/* Back on #map, where it was. Narrowing it to the tile pane saved a little
   work and changed how it looked, which was not a trade worth making. */
body.lockedmap #map::after{
  content:'';position:absolute;inset:0;z-index:500;pointer-events:none;
  background:#0B0E14;opacity:.55;mix-blend-mode:color}
body.lockedmap .leaflet-tile-pane{opacity:.86}
body.lockedmap .vignette{background:radial-gradient(ellipse 70% 70% at 50% 50%,rgba(3,5,10,.25) 30%,rgba(3,5,10,.7) 80%,rgba(3,5,10,.9) 100%)}
.lockmark{position:fixed;top:50%;left:calc(50% + 190px);transform:translate(-50%,-50%);
  z-index:460;pointer-events:none;color:rgba(255,255,255,.62);
  width:168px;height:168px;display:grid;place-items:center;
  border-radius:40px;background:rgba(8,11,18,.52);border:1px solid rgba(255,255,255,.11);
  box-shadow:0 24px 70px rgba(0,0,0,.45);
  animation:lockfloat 6s ease-in-out infinite}
.lockmark svg{width:82px;height:82px}
.lockmark svg *{stroke-width:1.9}
@keyframes lockfloat{0%,100%{transform:translate(-50%,-50%)}50%{transform:translate(-50%,calc(-50% - 9px))}}
@media (max-width:1100px){.lockmark{left:50%}}
@media (max-width:760px){.lockmark{top:34%;width:118px;height:118px;border-radius:30px}.lockmark svg{width:58px;height:58px}}
@media (prefers-reduced-motion:reduce){.lockmark{animation:none}}

.vignette{position:fixed;inset:0;pointer-events:none;z-index:450;
  background:radial-gradient(ellipse 78% 78% at 50% 50%,rgba(3,5,10,0) 42%,rgba(3,5,10,.55) 82%,rgba(3,5,10,.8) 100%)}
/* tiles arrive over this, so a gap reads as deep water rather than black */
.leaflet-container{font-family:var(--font);background:#0A0E15}
.leaflet-tile-pane{background:#0A0E15}
.leaflet-interactive{cursor:pointer}
/* lines live in custom panes, so target every path inside the map */
#map path{transition:stroke .25s ease,stroke-opacity .25s ease,stroke-width .25s ease}
.leaflet-control-zoom{display:none!important}
.leaflet-control-attribution{background:rgba(5,7,12,.66)!important;color:var(--dim)!important;backdrop-filter:blur(4px)}
.leaflet-control-attribution a{color:var(--dim)!important}
/* Panels that blur what's behind them have to re-snapshot the backdrop on
   every frame the map animates. Pushing each onto its own compositing layer
   stops that snapshot going stale, which is what made the top-right panel
   flash the map's own lines until a zoom forced a repaint. */
/* No forced compositing layers. Promoting these was a guess, and adding GPU
   layers over a map Leaflet is itself transforming is how tiles end up torn. */
/* switches used by tsBlur() and tsFlow() in the console, for isolating the
   flicker: one removes every backdrop blur, the other stops the dashes */
body.noblur *{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
body.noblur .spacebox,body.noblur .permpill,body.noblur .brandbar,body.noblur .sheet{background:#0B0F17!important}
body.noflow .flowline,body.noflow .flowrail{stroke-dashoffset:0!important}
/* The dashes are moved from JavaScript, one property write per frame, rather
   than by a CSS keyframe animation. A CSS animation on an SVG stroke property
   makes the browser re-rasterise the whole shared SVG layer every frame, and
   that is what made the lines — and the panels blurring the map behind them —
   flicker. The look is identical; only the mechanism changed. */
.flowline{stroke-dasharray:6 10}
.flowrail{stroke-dasharray:12 8}
/* Pause, don't remove. `animation:none` restarts the dash from zero every
   time the class flips, and zoom events fire in bursts — which is what made
   the lines strobe while zooming into a trip. */
/* the ticker itself rests while the map moves; nothing to pause in CSS */
/* Nothing animates while the tab is in the background. Browsers queue frames
   and flush them on return, which arrived as a burst of strobing. */
body.tabhidden *,body.tabhidden *:before,body.tabhidden *:after{animation-play-state:paused!important;transition:none!important}
.leaflet-tooltip{background:var(--glass);color:var(--ink);border:1px solid var(--hair2);box-shadow:0 4px 18px rgba(0,0,0,.5);backdrop-filter:blur(6px);border-radius:8px}
.leaflet-tooltip:before{display:none}
@keyframes rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes flashring{0%{box-shadow:0 0 0 0 var(--flash,rgba(140,164,255,.6))}100%{box-shadow:0 0 0 16px transparent}}
.legcard.flash,.vrow.flash{animation:flashring .9s ease-out}

/* status toast — pinned to the very bottom-right corner */
.toast{position:fixed;right:10px;bottom:10px;z-index:520;display:flex;align-items:center;gap:7px;background:var(--glass);border:1px solid var(--hair2);border-radius:99px;padding:7px 14px 7px 11px;font-size:11.5px;color:var(--ink);backdrop-filter:blur(8px);box-shadow:0 6px 22px rgba(0,0,0,.45);opacity:0;transform:translateY(6px);transition:opacity .28s ease,transform .28s ease;pointer-events:none}
/* The toast ignores the pointer so it never blocks the map underneath. But a
   toast with a button in it has to be reachable, so that one takes the pointer
   back — and only the button inside it, not the whole strip. */
.toast:has(.tundo){pointer-events:auto}
.toast .tundo{pointer-events:auto}
.toast.on{opacity:1;transform:none}
/* The way back sits in the toast itself, so nothing needs confirming first. A
   real button, reachable by keyboard, and the toast stays long enough to read
   and use. */
.tundo{margin-left:4px;border:1px solid var(--hair2);background:rgba(255,255,255,.06);
  color:var(--ink);font:inherit;font-weight:700;font-size:11.5px;
  padding:3px 9px;border-radius:7px;cursor:pointer;flex-shrink:0;
  transition:border-color .15s ease,background .15s ease}
.tundo:hover{border-color:var(--accent2);background:rgba(255,255,255,.1)}

/* centred over the map, clear of the wordmark on the left and the account
   panel on the right */
.permpill{position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:15;cursor:pointer;
  border:1px solid var(--hair2);background:var(--glass);backdrop-filter:blur(8px);
  border-radius:12px;padding:6px 13px 7px;text-align:center;box-shadow:0 8px 26px rgba(0,0,0,.45);transition:border-color .15s,transform .15s}
.permpill:hover{border-color:var(--accent2)}
/* Both of these come and go as you move around, so they fade and lift rather
   than blinking out. They keep their box while hidden — display:none cannot be
   transitioned — and are made unreachable with visibility and pointer-events
   instead, so nothing invisible can be clicked. */
/* visibility has to be in the transition, held until the fade has finished.
   Left out, it flips to hidden on the first frame and the element is gone
   before any of the opacity has been seen — which is why this still snapped. */
.permpill{transition:opacity .2s ease,transform .2s cubic-bezier(.22,.61,.36,1),
  border-color .18s ease,background .18s ease,visibility 0s linear 0s}
.permpill[hidden]{display:block!important;opacity:0;visibility:hidden;pointer-events:none;
  transform:translateX(-50%) translateY(-8px);
  transition:opacity .2s ease,transform .2s cubic-bezier(.22,.61,.36,1),visibility 0s linear .2s}
.ptop{font-size:10px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--ink);margin-bottom:5px;white-space:nowrap}
.prow{display:flex;align-items:center;gap:10px;justify-content:center}
.pperm{font-size:12px;font-weight:800;letter-spacing:-.01em;white-space:nowrap}
/* open to everyone is the state worth noticing, so it takes the warm colour;
   restricted is the settled one */
.pperm.yes{color:var(--warn)}
.pperm.no{color:var(--ok)}
.pdiv{width:1px;height:13px;background:var(--hair2)}
@media (max-width:1100px){.permpill{display:none}}
/* with only the account row in it, the panel keeps the padding it uses for a
   full one — which reads as a gap along the bottom */
/* With only the account row in it, the row's own bottom rule and margin left
   a gap. Removing them leaves the panel's own 9px padding on all four sides. */
/* Only the gap meant for the section below is removed. Zeroing the row's own
   padding as well left its content 17px from the top of the panel and 9px from
   the bottom, which is what looked cut off. */
.spacebox.bare .acchead{margin-bottom:0}
.spacebox{position:fixed;top:16px;right:16px;width:318px;z-index:500;background:var(--glass);border:1px solid var(--hair);border-radius:14px;padding:9px 11px;backdrop-filter:blur(8px);box-shadow:0 8px 32px rgba(0,0,0,.35)}
.spacebox{transition:opacity .2s ease,transform .2s cubic-bezier(.22,.61,.36,1),visibility 0s linear 0s}
.spacebox[hidden]{display:block!important;opacity:0;visibility:hidden;pointer-events:none;
  transform:translateY(-8px) scale(.985);
  transition:opacity .2s ease,transform .2s cubic-bezier(.22,.61,.36,1),visibility 0s linear .2s}
/* account block sitting above the space controls */
.acchead{display:flex;align-items:center;gap:10px;width:100%;text-align:left;border:1px solid var(--hair);background:rgba(255,255,255,.03);border-radius:11px;padding:8px 10px;margin-bottom:11px;cursor:pointer}
.acchead:hover{border-color:var(--acct);background:rgba(255,255,255,.06)}
/* a paid account should feel like one every time they glance at it */
.acchead.pro{border-color:rgba(79,195,255,.32);background:linear-gradient(150deg,rgba(143,230,255,.16),rgba(79,195,255,.07) 55%,rgba(255,255,255,.02))}
.acchead.pro:hover{border-color:rgba(79,195,255,.6);background:linear-gradient(150deg,rgba(143,230,255,.24),rgba(79,195,255,.12) 55%,rgba(255,255,255,.04))}
.acchead.out{cursor:default;justify-content:space-between}
.acchead.out:hover{border-color:var(--hair);background:rgba(255,255,255,.03)}
.acface{width:32px;height:32px;border-radius:50%;object-fit:cover;flex-shrink:0;border:1px solid var(--hair2)}
.acface.init{display:flex;align-items:center;justify-content:center;font-family:var(--disp);font-size:14px;font-weight:800;background:rgba(154,166,189,.2);color:var(--ink)}
.acctxt{display:block;min-width:0;flex:1}
.acname{display:block;font-weight:700;font-size:13px;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acsub .tierpill{margin-left:0;margin-right:6px;vertical-align:0}
.acsub{display:block;font-size:11px;color:var(--dim);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acchev{color:var(--dim);font-size:17px;line-height:1;flex-shrink:0}
.acclabel{font-size:11.5px;font-weight:600;color:var(--dim);flex-shrink:0;transition:opacity .18s ease}
/* Both words sit in the same cell and cross-fade. Nothing in JS writes the
   text or times the change, so the animation is the same every time rather
   than depending on whether the card happened to be redrawn. */
.acclabel{display:grid;align-items:center}
.lw{grid-area:1/1;transition:opacity .2s ease,transform .2s ease;white-space:nowrap}
.lwback{opacity:0;transform:translateY(5px)}
body.inprofile .lwacct{opacity:0;transform:translateY(-5px)}
body.inprofile .lwback{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.lw{transition:none}}
.acchev{transition:transform .28s cubic-bezier(.4,1.2,.5,1),color .2s ease}
/* while you're in the profile the same block is the way out */
body.inprofile .acchead .acclabel{color:var(--acct);order:2}
body.inprofile .acchead .acchev{order:1;transform:rotate(180deg);color:var(--acct)}
.acbtn{display:inline-flex;align-items:center;gap:7px;border:0;border-radius:9px;padding:6px 11px;background:#fff;color:#1B2430;font-size:12px;font-weight:700;cursor:pointer;flex-shrink:0}
.acbtn:hover{filter:brightness(.95)}
.sbbtn[disabled]{opacity:.4;cursor:not-allowed}
.sbhead{font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--dim);margin-bottom:6px}
.sbrow{display:flex;gap:6px;align-items:center}
.sbrow+.sbrow{margin-top:6px}
.sbsel{flex:1;min-width:0;height:34px;background-color:rgba(0,0,0,.3);color:var(--ink);border:1px solid var(--hair2);border-radius:8px;padding:0 34px 0 10px;font-size:12px;font-weight:700;cursor:pointer;text-overflow:ellipsis;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 6 L8 10.5 L12.5 6' stroke='%238E97A8' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 11px center;background-size:11px}
.sbbtn{border:1px solid var(--hair2);background:none;color:var(--dim);border-radius:8px;padding:5px 10px;font-size:11.5px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:4px;white-space:nowrap;flex-shrink:0}
.sbbtn:hover{color:var(--ink)}
.sbbtn.newspace{height:34px;padding:0 13px;font-size:12px;font-weight:700}
.sbbtn.danger{color:var(--err);border-color:rgba(255,122,107,.38)}
.sbbtn.danger:hover{color:var(--err);border-color:var(--err);background:rgba(255,122,107,.1)}
.copyspace.wide{width:100%}
.copyspace{flex:1;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:1px solid rgba(108,140,255,.45);background:linear-gradient(135deg,rgba(108,140,255,.22),rgba(108,140,255,.1));color:var(--accent2);border-radius:8px;padding:5px 10px;font-size:11.5px;font-weight:700;cursor:pointer;white-space:nowrap}
.copyspace:hover{filter:brightness(1.15)}
.spacebox.inline{position:static;width:auto;margin-top:14px;box-shadow:none;background:rgba(255,255,255,.02)}
/* The phone's account card: a panel across the top of the screen that comes
   down when the trip list is minimised, and lifts away when it isn't. */
/* Floating, like the sheet at the other end of the screen: the same 10px
   inset, the same rounded corners, its own border all the way round. */
.spacebox.drop{position:fixed;left:10px;right:10px;width:auto;
  top:calc(10px + env(safe-area-inset-top,0px));
  border-radius:16px;border-width:1px;padding:11px 13px;
  z-index:540;box-shadow:0 16px 40px rgba(0,0,0,.45);
  transform:translateY(calc(-100% - 24px - env(safe-area-inset-top,0px)));
  transition:transform .3s cubic-bezier(.22,.61,.36,1)}
.spacebox.drop.down{transform:none}
@media (prefers-reduced-motion:reduce){.spacebox.drop{transition:none}}

.col{position:fixed;left:16px;top:16px;bottom:16px;width:412px;z-index:500;display:flex;flex-direction:column;gap:10px;pointer-events:none}
.col>*{pointer-events:auto}
.brandbar{display:flex;align-items:center;flex-wrap:wrap;row-gap:6px;gap:6px;background:var(--glass);border:1px solid var(--hair);border-radius:14px;padding:10px 13px;backdrop-filter:blur(8px);box-shadow:0 8px 32px rgba(0,0,0,.35)}
/* the logo is the mode switcher: Plan is blue, Track is yellow */
.brandbar{position:relative;z-index:20}
.modebtn{display:flex;align-items:center;gap:4px;margin-right:auto;border:1px solid transparent;background:none;border-radius:11px;padding:3px 7px 3px 4px;cursor:pointer;color:var(--accent);transition:border-color .15s,background .15s}
.modebtn:hover{border-color:var(--hair2);background:rgba(255,255,255,.04)}
.modebtn .logo{display:block;flex-shrink:0}
.bname{font-family:var(--disp);font-size:17.5px;font-weight:800;letter-spacing:-0.03em;color:var(--ink)}
.bmode{font-family:var(--disp);font-size:17.5px;font-weight:800;letter-spacing:-0.03em;color:var(--accent)}
.bmode:before{content:'';display:inline-block;width:1px;height:13px;background:var(--hair2);margin:0 7px -1px 4px}
.bmode.track{color:var(--stay)}
.bmode.inspo{color:var(--inspo)}
.bmode.points{color:var(--points)}
.bmode.profile{color:var(--acct)}
.bcaret{color:var(--dim);display:block;flex-shrink:0;margin-left:2px;
  transition:transform .22s cubic-bezier(.22,.61,.36,1),color .15s ease}
/* The caret belongs to the area name: while there is no name to point at,
   there is nothing to open. One rule, so it cannot be left hidden by a code
   path that forgot to put it back. */
.bmode[hidden]+.bcaret{display:none}
/* nested views own the top bar, so the switcher steps out of the way */
body.nested .bcaret{display:none}
body.nested .modebtn{cursor:default}
body.nested .modebtn:hover{border-color:transparent;background:none}
body.track .modebtn{color:var(--stay)}
body.inspo .modebtn{color:var(--inspo)}
body.points .modebtn{color:var(--points)}
body.profile .modebtn{color:var(--acct)}
/* shared and sharing pages aren't switchable, so drop the switcher furniture */
body.viewonly .bmode,body.viewonly .bcaret{display:none}
body.inprofile .bmode{display:none}
/* the way out of a nested view wears the colour of where it goes back to */
.topbtn.backout{display:inline-flex;align-items:center;gap:6px;border-color:currentColor;color:var(--acct);background:rgba(255,255,255,.04)}
.topbtn.backout.plan{color:var(--accent2);border-color:rgba(108,140,255,.55);background:rgba(108,140,255,.12)}
.topbtn.backout.track{color:var(--stay);border-color:rgba(255,211,77,.55);background:rgba(255,211,77,.12)}
.topbtn.backout.inspo{color:var(--inspo);border-color:rgba(255,111,181,.55);background:rgba(255,111,181,.12)}
.topbtn.backout.points{color:var(--points);border-color:rgba(79,224,138,.55);background:rgba(79,224,138,.12)}
.topbtn.backout:hover{filter:brightness(1.15)}
.acface.init.guest{background:rgba(154,166,189,.16);color:var(--dim)}

/* the one Pro page */
.prowrap{padding:8px 2px}
.proheader{margin-bottom:16px}
.pricetag{display:flex;align-items:baseline;gap:9px;margin-top:14px;flex-wrap:wrap}
/* the trial is the offer, so it is the thing that reads loudest */
/* The gradient has to end where it began, or sliding it back to the start
   jumps. These stops are a palindrome and the slide covers exactly one tile,
   so the loop is continuous rather than snapping every six seconds. */
.trialbadge{font-family:var(--disp);font-size:26px;font-weight:800;letter-spacing:-.03em;line-height:1;
  background-image:linear-gradient(100deg,#BFD4FF 0%,#7FC8FF 25%,#B78CFF 50%,#7FC8FF 75%,#BFD4FF 100%);
  background-size:200% 100%;background-repeat:repeat;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:shimmer 7s linear infinite}
@keyframes shimmer{from{background-position:0 0}to{background-position:200% 0}}
@media (prefers-reduced-motion:reduce){.trialbadge{animation:none}}
.prthen{font-size:12.5px;color:var(--dim);align-self:flex-end;padding-bottom:2px}
/* each point arrives just after the one before it, so the page assembles
   rather than appearing all at once */
.perks.reveal .perk{opacity:0;animation:perkin .42s ease forwards}
.perks.reveal .perk:nth-child(1){animation-delay:.02s}
.perks.reveal .perk:nth-child(2){animation-delay:.08s}
.perks.reveal .perk:nth-child(3){animation-delay:.14s}
.perks.reveal .perk:nth-child(4){animation-delay:.20s}
.perks.reveal .perk:nth-child(5){animation-delay:.26s}
@keyframes perkin{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .perks.reveal .perk{opacity:1;animation:none}
  .trialbadge{animation:none}
}
.pramt{font-family:var(--disp);font-size:34px;font-weight:800;letter-spacing:-.035em;line-height:1;background:linear-gradient(100deg,#BFD4FF,#7FC8FF 45%,#B78CFF);-webkit-background-clip:text;background-clip:text;color:transparent}
.prper{font-size:12.5px;color:var(--dim)}

/* what you actually get, before the table of numbers */
.perks{display:flex;flex-direction:column;gap:10px;margin-bottom:18px}
.perk{display:flex;gap:11px;align-items:flex-start}
.pico{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:9px;flex-shrink:0;line-height:0}
.pico.blue{background:var(--accent2)}
.pico.sky{background:var(--fly)}
.pico.yellow{background:var(--stay)}
.pico.pink{background:var(--inspo)}
.pico.green{background:var(--points)}
.ptitle{font-weight:700;font-size:13.5px;letter-spacing:-.01em}
.pdesc{font-size:12px;color:var(--dim);line-height:1.45;margin-top:2px}
.trustrow{display:flex;align-items:center;justify-content:center;gap:7px;font-size:11px;color:var(--dim);margin:10px 0 6px}
.trustrow svg{flex-shrink:0;opacity:.8}

/* checkout, over the map rather than away from the site */
.ckout{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;justify-content:center;padding:20px;
  background:rgba(4,6,11,.72);backdrop-filter:blur(4px);opacity:0;transition:opacity .2s ease}
.ckout.open{opacity:1}
.ckcard{width:100%;max-width:460px;max-height:92vh;display:flex;flex-direction:column;overflow:hidden;
  background:#0B0F17;border:1px solid var(--hair2);border-radius:18px;box-shadow:0 30px 90px rgba(0,0,0,.7);
  transform:translateY(10px) scale(.985);transition:transform .28s cubic-bezier(.3,1.2,.5,1)}
.ckout.open .ckcard{transform:none}
.ckhead{display:flex;align-items:center;gap:11px;padding:14px 16px;border-bottom:1px solid var(--hair)}
.ckhead svg{flex-shrink:0}
.ckmeta{flex:1;min-width:0}
.cktitle{font-family:var(--disp);font-size:15px;font-weight:800;letter-spacing:-.02em}
.cktrial{display:inline-block;margin-left:6px;padding:2px 7px;border-radius:99px;font-family:var(--font);
  font-size:9.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;vertical-align:middle;
  color:#05070C;background:linear-gradient(100deg,#BFD4FF,#7FC8FF 50%,#B78CFF)}
.cksub{font-size:11.5px;color:var(--dim);margin-top:1px}
.ckx{border:0;background:none;color:var(--dim);font-size:15px;cursor:pointer;padding:4px 6px;line-height:1;flex-shrink:0}
.ckx:hover{color:var(--ink)}
.ckbody{flex:1;min-height:0;overflow-y:auto;padding:6px 10px 12px}
.ckload{padding:40px 0;text-align:center;font-size:12.5px;color:var(--dim)}
.ckerr{font-size:12px;color:var(--err);margin:9px 2px 0;min-height:0}
/* Welcome to Pro: one thing at a time, in the same card the rest of the app
   uses for anything that takes over the screen. Centred on every size — the
   sheet-style bottom alignment the checkout overlay uses on a phone is wrong
   for something you read rather than fill in. */
.prowelwrap{align-items:center!important;justify-content:center}
.prowel{max-width:430px;padding:0;overflow:hidden}
.prowelhead{display:flex;align-items:center;justify-content:space-between;padding:14px 15px 0}
.prowelkick{font-size:9.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  background:linear-gradient(100deg,#BFD4FF 0%,#7FC8FF 25%,#B78CFF 50%,#7FC8FF 75%,#BFD4FF 100%);
  background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
  animation:shimmer 7s linear infinite}
.prowelbody{padding:16px 22px 4px;text-align:center;min-height:186px}
/* Each card's contents arrive rather than appearing: the icon settles first,
   then the heading, then the words. The card is rebuilt on every step, so a
   plain animation runs afresh each time without any state to track. */
.pico.big{width:44px;height:44px;border-radius:14px;margin:0 auto 14px;display:grid;place-items:center;
  animation:picoin .5s cubic-bezier(.22,1.1,.36,1) both}
.prowelt{font-family:var(--disp);font-size:19px;font-weight:800;letter-spacing:-.02em;margin:0 0 8px;
  animation:stepin .42s ease both .06s}
.proweld{font-size:13px;line-height:1.62;color:var(--dim);margin:0;
  animation:stepin .42s ease both .12s}
@keyframes picoin{
  from{opacity:0;transform:translateY(9px) scale(.82) rotate(-8deg)}
  to{opacity:1;transform:none}
}
@keyframes stepin{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .pico.big,.prowelt,.proweld{animation:none}
}
.proweldots{display:flex;gap:5px;justify-content:center;padding:14px 0 2px}
.pwdot{width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,.18);transition:background .2s ease,width .2s ease}
.pwdot.on{width:16px;border-radius:3px;background:var(--accent2)}
.prowelrow{display:flex;gap:8px;align-items:center;padding:12px 15px 15px}
.prowelrow .sbbtn{flex:0 0 auto}
.sbbtn.ghost{border-color:transparent;color:var(--dim)}
.pwnext{flex:1;margin:0}
@media (prefers-reduced-motion:reduce){.prowelkick{animation:none}.pwdot{transition:none}}
@media (max-width:760px){.prowel{max-width:none;width:100%}.prowelbody{min-height:210px;padding:16px 18px 4px}}
.ckpay{margin:12px 0 0;width:100%}
.cknote{font-size:11px;color:var(--dim);line-height:1.5;margin:9px 2px 2px;text-align:center}
@media (max-width:560px){
  .ckout{padding:0;align-items:flex-end}
  /* the welcome is read, not filled in: centred, with room around it */
  .ckout.prowelwrap{padding:18px}
  .ckcard{max-width:none;max-height:94vh;border-radius:18px 18px 0 0}
  /* After .ckcard, not before it. Both are single classes, so whichever comes
     last wins — and the sheet's square bottom corners were winning. */
  .ckcard.prowel{border-radius:18px}
}
.prokicker{font-size:10px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--accent2);margin-bottom:6px}
.prohead2{font-family:var(--disp);font-size:22px;font-weight:800;letter-spacing:-.025em;margin:0 0 6px;line-height:1.15}
.prolede{font-size:13px;color:var(--dim);margin:0 0 16px}
.protable{width:100%;border-collapse:collapse;font-size:12.5px;margin-bottom:16px}
.protable th{font-size:9.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);text-align:right;padding:0 0 7px;font-weight:700}
.protable th:first-child{text-align:left}
.protable td{padding:8px 0;border-top:1px solid var(--hair);text-align:right;color:var(--dim);font-variant-numeric:tabular-nums}
.protable td:first-child{text-align:left;color:var(--ink)}
.protable .p{color:var(--accent2);font-weight:700}
.addtrip.pro{background:linear-gradient(135deg,#7FC8FF,#7C97FF 45%,#B78CFF);color:#070B18}
.addtrip.pro[disabled]{opacity:.55;cursor:default;transform:none;filter:none}
body.viewonly .modebtn{cursor:default;padding-left:4px}
body.viewonly .modebtn:hover{border-color:transparent;background:none}
.modemenu{position:absolute;top:calc(100% + 6px);left:10px;z-index:600;min-width:238px;background:rgba(16,21,30,.98);border:1px solid var(--hair2);border-radius:13px;padding:5px;box-shadow:0 18px 46px rgba(0,0,0,.7);backdrop-filter:blur(8px)}
/* The menu drops out of the button rather than appearing. It keeps its box
   while closed — display:none cannot be transitioned — and is made unreachable
   with visibility and pointer-events, so nothing invisible can be clicked or
   tabbed into. Visibility is held until the fade finishes; left out of the
   transition it flips on the first frame and the animation is never seen. */
.modemenu{transform-origin:top left;opacity:1;transform:none;
  transition:opacity .16s ease,transform .2s cubic-bezier(.22,.61,.36,1),visibility 0s linear 0s}
.modemenu[hidden]{display:block!important;opacity:0;visibility:hidden;pointer-events:none;
  transform:translateY(-8px) scale(.96);
  transition:opacity .16s ease,transform .2s cubic-bezier(.22,.61,.36,1),visibility 0s linear .2s}
.mm{display:block;width:100%;text-align:left;border:0;background:none;border-radius:9px;padding:8px 10px;cursor:pointer}
.mm:hover{background:rgba(255,255,255,.07)}
.mmt{display:block;font-family:var(--disp);font-size:15px;font-weight:800;letter-spacing:-0.02em}
.mmt.plan{color:var(--accent)}
.mmt.track{color:var(--stay)}
.mmt.inspo{color:var(--inspo)}
.mmt.points{color:var(--points)}
.mmt.profile{color:var(--acct)}
.mms{display:block;font-size:11.5px;color:var(--dim);margin-top:1px}
/* the title keeps its colour; everything else dims and gains a padlock */
.mm{position:relative;
  transition:opacity .2s ease,transform .24s cubic-bezier(.22,.61,.36,1),background .15s ease}
/* The items arrive just behind the menu, one after another. */
.modemenu[hidden] .mm{opacity:0;transform:translateY(-5px)}
.modemenu:not([hidden]) .mm{opacity:1;transform:none}
.modemenu:not([hidden]) .mm:nth-child(1){transition-delay:.03s}
.modemenu:not([hidden]) .mm:nth-child(2){transition-delay:.06s}
.modemenu:not([hidden]) .mm:nth-child(3){transition-delay:.09s}
.modemenu:not([hidden]) .mm:nth-child(4){transition-delay:.12s}
/* The caret turns over while it is open, so the button shows its own state. */
.modebtn[aria-expanded="true"] .bcaret{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){
  .modemenu,.modemenu .mm,.bcaret{transition:none}
  .modemenu[hidden] .mm{opacity:1;transform:none}
}
.mm.locked .mms{opacity:.45}
.mm.locked .mmt{opacity:.72}
.mmlock{position:absolute;top:50%;right:10px;transform:translateY(-50%);color:var(--dim);line-height:0}
.mm.locked:hover .mmlock{color:var(--ink)}
.hgroup{display:inline-flex;border:1px solid var(--hair2);border-radius:9px;overflow:hidden;flex-shrink:0}
.hgroup button{border:0;background:none;color:var(--dim);padding:5px 8px;font-size:11px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;line-height:0}
.hgroup button:hover:not([disabled]){color:var(--ink);background:rgba(255,255,255,.06)}
.hgroup[hidden]{display:none}
.hgroup button[disabled]{opacity:.3;cursor:default}
.hgroup button+button{border-left:1px solid var(--hair2)}
.topbtn{border:1px solid var(--hair2);background:rgba(255,255,255,.04);color:var(--ink);border-radius:99px;padding:5px 13px;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0}
.topbtn:hover{border-color:rgba(108,140,255,.55);color:var(--accent2)}
.topbtn[hidden]{display:none}
.topbtn.on{background:rgba(108,140,255,.2);border-color:rgba(108,140,255,.6);color:var(--accent2)}
a.topbtn{text-decoration:none;display:inline-flex;align-items:center}
.vlbtn svg,.topbtn svg,.sbbtn svg,.copyspace svg,.selbar button svg{display:block;flex-shrink:0}
.vlbtn svg{transform:translateY(-1.7px)}
.topbtn.cta-own{background:linear-gradient(135deg,#7C97FF,#5B7BF0);border-color:transparent;color:#070B18;font-weight:700}
.topbtn.cta-own:hover{filter:brightness(1.08);color:#070B18}
/* the Track version only — the blue one on shared trip plans is untouched */
.topbtn.cta-own.track{background:linear-gradient(135deg,#FFD34D,#FFA43D 55%,#FF8A4D);color:#1A1206}
.topbtn.cta-own.track:hover{filter:brightness(1.08);color:#1A1206}

.sheetwrap{flex:1;min-height:0;display:flex;flex-direction:column;border-radius:var(--r);overflow:hidden;box-shadow:0 14px 44px rgba(0,0,0,.42)}
.sheet{flex:1;min-height:0;background:var(--glass);border:1px solid var(--hair);border-radius:var(--r);backdrop-filter:blur(8px);overflow-y:auto;overflow-x:hidden;padding:16px 13px 16px 16px;animation:rise .35s ease;clip-path:inset(0 round var(--r))}
.sheet{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.16) transparent}
.fadein{animation:rise .32s ease}
.sheet::-webkit-scrollbar{width:7px}
.sheet::-webkit-scrollbar-track{background:transparent}
.sheet::-webkit-scrollbar-thumb{background:rgba(255,255,255,.16);border-radius:99px}
.sheet::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.26)}

.totalchip{display:none;flex-direction:column;gap:7px;background:var(--glass);border:1px solid var(--hair);border-radius:14px;padding:11px 14px;backdrop-filter:blur(8px);box-shadow:0 8px 28px rgba(0,0,0,.35)}
.tcrow{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.tcbooked{font-family:var(--disp);font-size:19px;font-weight:800;letter-spacing:-0.02em}
.tcbooked.done{color:var(--ok)}
.tcbooked small{font-family:var(--font);font-size:11px;font-weight:600;color:var(--dim);letter-spacing:.06em;text-transform:uppercase;margin-left:6px}
.tckm{font-family:var(--mono);font-size:12.5px;color:var(--dim);font-variant-numeric:tabular-nums;white-space:nowrap}
.tcbar{position:relative;height:12px;border-radius:99px;background:rgba(255,255,255,.07);overflow:hidden}
.tcfill{position:absolute;inset:0 auto 0 0;border-radius:99px;background:linear-gradient(90deg,#7FC8FF,#5FE3B0);transition:width .45s cubic-bezier(.4,1.3,.5,1)}
.tcplane{position:absolute;top:50%;transition:left .45s cubic-bezier(.4,1.3,.5,1);line-height:0;filter:drop-shadow(0 1px 3px rgba(0,0,0,.7))}

.hero{padding:52px 10px 4px;text-align:center;color:var(--dim)}
.hero.tucked{padding-top:34px}
.hero .mark{margin:0 auto 22px;display:block}
.hero h2{font-family:var(--disp);color:var(--ink);font-size:27px;font-weight:800;letter-spacing:-0.025em;margin:0 0 10px;line-height:1.1}
.hero p{margin:0 auto 22px;font-size:13.5px;white-space:nowrap}
.feats{display:flex;gap:13px;justify-content:center;margin-top:22px;opacity:.55;align-items:center}

.primary{display:inline-block;border:0;border-radius:11px;padding:12px 26px;background:linear-gradient(135deg,#7C97FF,#5B7BF0);color:#070B18;font-weight:700;cursor:pointer;text-decoration:none;box-shadow:0 6px 20px rgba(108,140,255,.28)}
.primary:hover{filter:brightness(1.07)}
.primary.block{display:block;width:100%;text-align:center}
/* The Plan blue through to a lighter blue, rather than running off into
   violet. A little extra padding on the right so the icon and the words sit
   left of centre together: with the icon before the text, dead centre reads
   as leaning right. */
.addtrip{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;border:0;border-radius:13px;padding:13px 20px;padding-right:27px;background:linear-gradient(135deg,#6C8CFF,#7FC8FF 55%,#5FE3B0 130%);color:#070B18;font-family:var(--disp);font-weight:800;font-size:15px;letter-spacing:-0.01em;cursor:pointer;box-shadow:0 8px 24px rgba(108,140,255,.3);margin-top:4px}
.addtrip:hover{filter:brightness(1.08);transform:translateY(-1px)}
.addtrip.track{background:linear-gradient(135deg,#FFD34D,#FFA43D 55%,#FF8A4D);color:#1A1206;box-shadow:0 8px 24px rgba(255,168,61,.28)}
.addtrip.inspo{background:linear-gradient(135deg,#FFA6DA,#FF6FB5 55%,#E84BC9);color:#20060F;box-shadow:0 8px 24px rgba(255,111,181,.28)}
.addtrip.acct{display:inline-flex;width:auto;gap:10px;background:#fff;color:#1B2430;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.addtrip.acct:hover{filter:brightness(.96)}

/* account chip in the top bar */
.acctchip{width:28px;height:28px;border-radius:50%;border:1px solid var(--hair2);background:rgba(255,255,255,.06);padding:0;cursor:pointer;overflow:hidden;flex-shrink:0;display:flex;align-items:center;justify-content:center}
.acctchip[hidden]{display:none}
.acctchip:hover{border-color:var(--acct)}
.acctchip img{width:100%;height:100%;object-fit:cover;display:block}
.acctchip .initial{font-weight:800;font-size:12.5px;color:var(--ink)}

/* profile */
.prohead{display:flex;align-items:center;gap:13px;margin-bottom:16px}
.proface{width:56px;height:56px;border-radius:50%;object-fit:cover;border:2px solid var(--hair2);flex-shrink:0}
.proface.init{display:flex;align-items:center;justify-content:center;font-family:var(--disp);font-size:24px;font-weight:800;background:rgba(154,166,189,.18);color:var(--ink)}
.proname{display:flex;align-items:center;gap:9px;font-family:var(--disp);font-size:21px;font-weight:800;letter-spacing:-.02em}
.protier{font-size:11.5px;color:var(--dim);margin-top:3px}
/* a switch, so the state is visible without reading the label */
.switchrow{display:flex;align-items:center;gap:10px;width:100%;border:1px solid var(--hair2);background:rgba(255,255,255,.03);border-radius:11px;padding:6px 11px;cursor:pointer;text-align:left}
.switchrow:hover{border-color:var(--hair2);background:rgba(255,255,255,.06)}
.swtxt{flex:1;font-size:12.5px;color:var(--dim);font-weight:600}
.swtxt{transition:color .25s ease}
.switchrow.on .swtxt{color:var(--stay)}
.switch{position:relative;width:34px;height:19px;border-radius:99px;background:rgba(255,255,255,.12);flex-shrink:0;transition:background .2s}
.switchrow.on .switch{background:var(--stay)}
.knob{position:absolute;top:3px;left:3px;width:13px;height:13px;border-radius:50%;background:#fff;transition:transform .2s cubic-bezier(.4,1.3,.5,1);box-shadow:0 1px 4px rgba(0,0,0,.5)}
.switchrow.on .knob{transform:translateX(15px)}
.unamerow{display:flex;gap:6px}
.unamerow input{flex:1;min-width:0}
.unamerow .sbbtn{flex-shrink:0;gap:5px}
.unamerow .sbbtn{border-color:rgba(255,211,77,.5);color:var(--stay)}
.unamerow .sbbtn:hover{background:rgba(255,211,77,.12);border-color:var(--stay)}
.unamerow .sbbtn svg{transform:translateY(-0.8px)}
.unamerow input,.unamerow .sbbtn{height:36px}
.unamerow .sbbtn{padding:0 13px}
.tierpill{display:inline-block;border-radius:99px;padding:1px 9px;font-size:10.5px;font-weight:800;margin-right:5px}
.tierpill{display:inline-flex;align-items:center;justify-content:center;font-size:9.5px;font-weight:800;letter-spacing:.09em;padding:4px 9px 3px;line-height:1;flex-shrink:0;position:relative;top:-1px}
.acsub .tierpill{top:0}
.tierpill.free{background:rgba(255,255,255,.11);color:var(--dim)}
/* the gradient drifts across the badge rather than sitting still */
/* the gradient starts and ends on the same colour and travels exactly one
   tile width, so the loop point can't be seen */
.tierpill.pro{color:#04212E;background:linear-gradient(100deg,#4FC3FF,#BFF0FF 25%,#4FC3FF 50%,#BFF0FF 75%,#4FC3FF);background-size:200% 100%;animation:proshine 5s linear infinite;box-shadow:0 0 14px rgba(79,195,255,.35)}
@keyframes proshine{from{background-position:0 0}to{background-position:-200% 0}}

/* usage, rather than a list of numbers you have to hold in your head */
.usebox{border:1px solid var(--hair);background:rgba(255,255,255,.02);border-radius:13px;padding:5px 10px 9px;margin-bottom:18px}
/* pro wears the baby blue; free keeps the plain panel */
.usebox.pro{border-color:rgba(79,195,255,.32);background:linear-gradient(150deg,rgba(143,230,255,.14),rgba(79,195,255,.06) 55%,rgba(255,255,255,.02))}
.usebox.pro .mfill{background:linear-gradient(90deg,#EAF9FF,#8FE6FF)}
.usebox.pro .mlbl{color:#BFE9FF}
.meter+.meter{margin-top:9px}
.mtop{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:5px}
.mlbl{font-size:11.5px;color:var(--dim)}
.mnum{font-family:var(--disp);font-size:14px;font-weight:800;letter-spacing:-.02em}
.mof{font-family:var(--font);font-size:11px;font-weight:600;color:var(--dim)}
.mtrack{height:11px;border-radius:99px;background:rgba(255,255,255,.08);overflow:hidden}
.mfill{height:100%;border-radius:99px;background:linear-gradient(90deg,#7FC8FF,#5FE3B0);transition:width .4s cubic-bezier(.4,1.3,.5,1)}
.meter.hot .mfill,.usebox.pro .meter.hot .mfill{background:linear-gradient(90deg,#FF9A5D,#FF6F6B)}
.meter.hot .mnum{color:var(--err)}
.mnote{font-size:10.5px;color:var(--dim);margin-top:4px}
/* cancelled but still running: not a warning, not business as usual */
.sbbtn.warn{border-color:rgba(255,138,77,.5);color:var(--warn)}
.sbbtn.warn:hover{background:rgba(255,138,77,.12);border-color:var(--warn);color:var(--warn)}
.sbbtn.go{border-color:rgba(95,227,176,.5);color:var(--ok)}
.sbbtn.go:hover{background:rgba(95,227,176,.12);border-color:var(--ok);color:var(--ok)}

/* space manager */
.spacelist{display:flex;flex-direction:column;gap:6px}
/* the two groups sit exactly as far apart as two rows do */
.spacelist+.spacelist{margin-top:6px}
/* the other spaces fold away; tall enough for several, scrolling past that */
.spacefold{margin-top:6px;margin-bottom:0}
.spacefold .foldinner{padding:11px 0 2px}
.spacefold.open .foldbody{max-height:420px;overflow-y:auto}
.spacelist:last-of-type{margin-bottom:7px}
.spacerow{border:1px solid var(--hair);background:rgba(255,255,255,.02);border-radius:11px;padding:9px 10px}
.spacerow.cur{border-color:rgba(108,140,255,.45);background:rgba(108,140,255,.08)}
/* arriving from the pill: a ring of blue so the eye lands in the right place */
.spacerow.cur.pulse{animation:rowpulse 1.3s cubic-bezier(.3,1,.4,1)}
@keyframes rowpulse{
  0%{box-shadow:0 0 0 0 rgba(108,140,255,.55)}
  60%{box-shadow:0 0 0 12px rgba(108,140,255,0)}
  100%{box-shadow:0 0 0 0 rgba(108,140,255,0)}
}
.srtag{display:flex;align-items:baseline;gap:8px;margin-bottom:7px}
.sropen{border:0;background:none;color:var(--dim);font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;cursor:pointer;padding:0}
.sropen:hover{color:var(--accent2)}
.srmain{display:flex;align-items:center;gap:7px}
.srtrips{font-size:11px;color:var(--dim);flex-shrink:0;white-space:nowrap;margin-left:auto}
/* the lock explains itself in place, so nothing needs explaining underneath */
/* just the padlock, big enough to read at a glance and to hit */
/* the padlock alone never said what pressing it would do */
/* the same 36px as the name box above, so the row reads as one stack */
.srlock{display:flex;align-items:center;gap:9px;width:100%;height:36px;margin-top:6px;border:1px solid var(--hair2);background:rgba(255,255,255,.03);color:var(--dim);border-radius:10px;padding:0 11px;cursor:pointer;text-align:left}
/* the fade belongs to the state change, not to the pointer passing over it */
.srlock.fading{transition:background .35s ease,border-color .35s ease,color .35s ease}
.srlock svg{flex-shrink:0}
.lkico{display:flex;align-items:center;line-height:0;flex-shrink:0;transform:translateY(-1px)}
.srlock.busy{cursor:default;opacity:.85}
.srlock.busy .lkico svg{animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.lkmain{flex:1;font-size:11.5px;font-weight:600}
.lkgo{font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);border:1px solid var(--hair2);border-radius:99px;padding:3px 9px;flex-shrink:0}
.srlock:hover{color:var(--ink);border-color:var(--hair2)}
.srlock:hover .lkgo{color:var(--ink)}
.srlock.on{color:var(--ok);border-color:rgba(95,227,176,.45);background:rgba(95,227,176,.09)}
.srlock.on .lkgo{color:var(--ok);border-color:rgba(95,227,176,.45)}
.sricon{border:1px solid var(--hair2);background:none;color:var(--dim);border-radius:9px;padding:5px 8px;cursor:pointer;line-height:0}
.sricon:hover{color:var(--ink)}
.srdel{display:inline-flex;align-items:center;justify-content:center;gap:7px;flex-shrink:0;border:1px solid rgba(255,122,107,.4);background:rgba(255,122,107,.09);color:var(--err);border-radius:10px;height:36px;padding:0 13px;font-size:11.5px;font-weight:700;cursor:pointer}
/* both children centred on the same axis, so the bin can't ride low */
.srdel svg{display:block;flex-shrink:0;transform:translateY(-0.8px)}
.srdel span{display:block;line-height:1;transform:translateY(0.5px)}
.srdel:hover{background:rgba(255,122,107,.18);border-color:var(--err)}
.sricon.srgo{font-size:15px;line-height:1;padding:3px 9px}
/* the count sits in its own compartment at the end of the name field */
/* one cell, one outline: the input inside carries no border of its own */
.srnamebox{display:flex;align-items:stretch;flex:1;min-width:0;height:36px;border:1px solid var(--hair2);background:rgba(0,0,0,.28);border-radius:9px;overflow:hidden;transition:border-color .15s}
.srnamebox:focus-within{border-color:var(--stay)}
input.srname,.pfield input.srname{flex:1;min-width:0;height:auto;border:0;background:none;box-shadow:none;color:var(--ink);font-family:var(--font);font-weight:700;font-size:12.5px;padding:0 10px;text-overflow:ellipsis;border-radius:0}
input.srname:focus,.pfield input.srname:focus{outline:none;border:0;box-shadow:none}
.srcount{display:flex;align-items:center;padding:0 11px 0 4px;font-size:10.5px;font-weight:700;color:var(--dim);white-space:nowrap}
.srhere{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--accent2)}
.promorow{display:flex;gap:6px}
/* it sits inside the fold-out, not inside a .pfield, so it can't inherit —
   which is what left it as a raw white browser input */
.promowrap{position:relative;display:flex;flex:1;min-width:0}
.promox{position:absolute;right:6px;top:50%;transform:translateY(-50%);border:0;background:none;
  color:var(--dim);font-size:12px;line-height:1;cursor:pointer;padding:4px 5px;border-radius:6px}
.promox:hover{color:var(--err);background:rgba(255,122,107,.12)}
.promorow input{flex:1;min-width:0;height:36px;border:1px solid var(--hair2);border-radius:9px;padding:0 10px;
  background:rgba(0,0,0,.3);color:var(--ink);font-family:var(--font);font-size:13px;font-weight:700;
  text-transform:uppercase;letter-spacing:.04em}
.promowrap input{padding-right:28px}
.promorow input::placeholder{color:var(--dim);font-weight:500;letter-spacing:0}
.promorow input:focus{outline:none;border-color:var(--ok);box-shadow:0 0 0 3px rgba(95,227,176,.16)}
.promorow .sbbtn{height:36px}
/* plan and usage read as one thing: joined edges, no gap between them */
.planwrap{margin-bottom:14px}
.planwrap .planrow{border-radius:11px 11px 0 0;border-bottom:0;margin-bottom:0}
.planwrap .usebox{border-radius:0 0 11px 11px;margin-bottom:0}
.planwrap.pro .planrow{border-color:rgba(79,195,255,.32)}
.planrow{display:flex;align-items:center;gap:10px;border:1px solid var(--hair);background:rgba(255,255,255,.02);border-radius:11px;padding:10px 11px;margin-bottom:8px}
.planrow.pro{border-color:rgba(79,195,255,.32);background:linear-gradient(150deg,rgba(143,230,255,.14),rgba(79,195,255,.06) 55%,rgba(255,255,255,.02))}
.planrow.pro .plansub{color:#BFE9FF}
.planmeta{flex:1;min-width:0}
.planname{font-family:var(--disp);font-size:15px;font-weight:800;letter-spacing:-.02em}
.plansub{font-size:11.5px;color:var(--dim);margin-top:2px}
.plansub b{color:var(--ink)}
.planrow .tierpill{top:0}
/* a headline first, then cards that carry a colour and an icon rather than
   six identical grey boxes */
/* One card for the lot. Its surface is a blend of the four colours the counts
   beneath are drawn in, so the card belongs to the numbers rather than being a
   grey box they happen to sit in. Four soft pools, one per colour, in the
   corners they sit nearest. */
.statcard{position:relative;overflow:hidden;border-radius:15px;padding:14px 15px 12px;
  border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.02);margin-bottom:12px}
/* The wash sits inside the card and carries the card's own corners, rather
   than overflowing and relying on the parent to clip it. Safari does not clip
   a filtered child to a rounded corner, which left the bottom left of this
   card square. The blur is gone for the same reason: the gradients are soft
   enough without it, and it was what triggered the bug. */
.statcard:before{content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:
    radial-gradient(64% 74% at 6% 4%,var(--fly),transparent 62%),
    radial-gradient(60% 70% at 96% 6%,var(--drv),transparent 62%),
    radial-gradient(66% 76% at 14% 98%,var(--stay),transparent 62%),
    radial-gradient(62% 72% at 94% 96%,var(--ok),transparent 62%);
  opacity:.17}
.statcard>*{position:relative}
/* The distance leads, in all four colours at once. */
.scnum{font-family:var(--disp);font-size:32px;font-weight:800;letter-spacing:-.035em;line-height:1;
  background-image:linear-gradient(100deg,var(--fly) 0%,var(--ok) 26%,var(--stay) 52%,var(--drv) 76%,var(--fly) 100%);
  background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
  animation:shimmer 9s linear infinite}
.scsub{font-size:12px;color:var(--dim);margin-top:5px}
/* The four counts on one line, each in its own colour, no boxes. */
.scrow{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-top:13px;
  padding-top:11px;border-top:1px solid rgba(255,255,255,.07)}
.sc{display:flex;flex-direction:column;gap:2px;min-width:0}
.scv{font-family:var(--disp);font-size:17px;font-weight:800;letter-spacing:-.02em;line-height:1.1;
  color:var(--c);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim2,#7D879B)}
.sc.fly{--c:var(--fly)}
.sc.globe{--c:var(--drv)}
.sc.stay{--c:var(--stay)}
.sc.tick{--c:var(--ok)}
@media (prefers-reduced-motion:reduce){.scnum{animation:none}}

/* the diagonal colour wash on six cards at once was the mess. One tinted chip
   each, everything on a single baseline, nothing competing. */

.stat 
.stat 

.profbox{border:1px solid var(--hair);background:rgba(255,255,255,.02);border-radius:12px;padding:11px}
.profbox .switchrow{border:0;background:none;padding:0;width:100%}
.profbox .switchrow:hover{background:none}
.profsplit{height:1px;background:var(--hair);margin:11px -11px}
/* The switch is the last thing in the box, so it needs room beneath it as well
   as above, and the box needs a clear gap before the next heading. Without both
   the photo line and "Spaces you own" read as one run of text. */
.profbox .switchrow{margin-top:2px;padding:2px 0 3px}
.pfield.acctfield{margin-bottom:22px}
.sublbl{display:block;font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);margin-bottom:5px}
.unamebox{border:1px solid rgba(154,166,189,.35);background:rgba(154,166,189,.07);border-radius:12px;padding:11px}
.unamebox .addtrip{margin-top:9px}
.phint.good{color:var(--ok)}
.phint.bad{color:var(--err)}
.ownrow{font-size:12.5px;color:var(--dim);border:1px solid var(--hair);border-radius:9px;padding:8px 10px;display:flex;align-items:center;gap:7px}
.ownrow.ok{color:var(--ok);border-color:rgba(95,227,176,.35);background:rgba(95,227,176,.06)}
.soonbox.acct{border-color:rgba(154,166,189,.3);background:rgba(154,166,189,.06)}
.soonbox.acct .soonlbl{color:var(--acct)}

/* points */
.ptsmark{width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:var(--points);border:2px solid rgba(5,7,12,.7);box-shadow:0 0 0 4px rgba(79,224,138,.2),0 3px 12px rgba(0,0,0,.75);animation:popin .32s cubic-bezier(.3,1.5,.5,1),drift 5s ease-in-out infinite alternate}
@keyframes drift{from{transform:translate(0,0)}to{transform:translate(var(--dx,4px),-7px)}}
.soonbox{margin-top:20px;border:1px solid rgba(79,224,138,.28);background:rgba(79,224,138,.06);border-radius:14px;padding:13px;text-align:left}
.soonlbl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--points);margin-bottom:6px}
.soonbox p{font-size:12px;color:var(--dim);line-height:1.55;margin:0;white-space:normal}

/* inspo */
.askbox{border:1px solid rgba(255,111,181,.28);background:rgba(255,111,181,.06);border-radius:14px;padding:12px;margin-bottom:12px}
.askq{font-family:var(--disp);font-size:16px;font-weight:800;letter-spacing:-0.02em;margin-bottom:9px}
.asklbl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);margin:10px 0 6px}
.chiprow{display:flex;flex-wrap:wrap;gap:5px}
.chip{border:1px solid var(--hair2);background:rgba(255,255,255,.03);color:var(--dim);border-radius:99px;padding:5px 11px;font-size:11.5px;font-weight:600;cursor:pointer}
.chip:hover{color:var(--ink);border-color:rgba(255,111,181,.5)}
.chip.on{background:rgba(255,111,181,.18);border-color:var(--inspo);color:#FFD9EE}
.clearchips{margin-top:9px;border:0;background:none;color:var(--dim);font-size:11.5px;font-weight:600;cursor:pointer;text-decoration:underline}
.clearchips:hover{color:var(--ink)}
.feedwait{border:1px dashed var(--hair2);border-radius:12px;padding:22px 14px;text-align:center;font-size:12.5px;color:var(--dim)}
.cattag{display:inline-block;background:rgba(255,111,181,.18);color:#FFD9EE;border-radius:99px;padding:1px 8px;font-size:10.5px;font-weight:700}
.tripcard.post .blurb{font-size:11.5px;color:var(--dim);font-style:italic;margin-top:4px}
.yours{font-size:10px;font-weight:700;color:var(--inspo);background:rgba(255,111,181,.16);border-radius:99px;padding:1px 7px;vertical-align:middle}
.roflag.inspo{color:var(--inspo);border-color:rgba(255,111,181,.4)}
.postblurb{font-size:13px;color:var(--ink);font-style:italic;margin-top:8px}
.postby{font-size:11.5px;color:var(--dim);margin-top:5px}
.postlegs{margin-top:12px}

/* travellers */
.tripcard.person .tname{font-size:15.5px}
.dimmed{color:var(--dim)}
.tstat{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--dim);margin-top:4px}
.tstat .dot{width:7px;height:7px;border-radius:50%;background:var(--dim);flex-shrink:0}
.tstat.ground{color:var(--ok)}
.tstat.ground .dot{background:var(--ok);box-shadow:0 0 0 3px rgba(95,227,176,.18)}
.tstat.air{color:var(--fly)}
.tstat.air .dot{background:var(--fly);box-shadow:0 0 0 3px rgba(127,200,255,.18)}
.tstat.big{font-size:13px;font-weight:600;border:1px solid var(--hair);background:rgba(255,255,255,.02);border-radius:11px;padding:9px 12px;margin-bottom:10px}
.pfield{margin-bottom:11px}
.pfield label{display:block;font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);margin-bottom:4px}
.pfield input,.pfield select{width:100%;border:1px solid var(--hair2);border-radius:9px;padding:7px 9px;background:rgba(0,0,0,.3);color:var(--ink);font-size:13px}
.pfield select{cursor:pointer}
.pfield input:focus,.pfield select:focus{border-color:var(--stay);outline:none}
.phint{font-size:11px;color:var(--dim);margin-top:4px;line-height:1.45}
.pshare{border:1px solid var(--hair2);border-radius:12px;padding:11px;margin-bottom:11px;background:rgba(255,211,77,.05)}
.pslbl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--stay);margin-bottom:5px}
.pslink{font-family:var(--mono);font-size:11px;color:var(--ink);word-break:break-all;background:rgba(0,0,0,.32);border-radius:8px;padding:7px 9px;margin-bottom:7px}
.psrow{display:flex;gap:6px}
.sbbtn.wide{width:100%;padding:8px}

/* live markers */
.permark,.airmark{position:relative;width:30px;height:30px;display:flex;align-items:center;justify-content:center}
.permark .face{position:relative;z-index:2;width:22px;height:22px;border-radius:50%;background:var(--pc);color:#0B0F17;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;border:2px solid rgba(5,7,12,.85);box-shadow:0 2px 10px rgba(0,0,0,.8)}
.permark .pulse,.airmark .ring{position:absolute;inset:2px;border-radius:50%;border:2px solid var(--pc);opacity:.55;animation:tpulse 2.2s ease-out infinite}
@keyframes tpulse{0%{transform:scale(.55);opacity:.75}70%{transform:scale(1.35);opacity:0}100%{opacity:0}}
.popmark{width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:var(--stay);border:2px solid rgba(5,7,12,.7);box-shadow:0 0 0 4px rgba(255,211,77,.22),0 3px 12px rgba(0,0,0,.75);animation:popin .32s cubic-bezier(.3,1.5,.5,1)}
@keyframes popin{0%{transform:scale(.2);opacity:0}100%{transform:scale(1);opacity:1}}
.airmark .plane{position:relative;z-index:2;line-height:0;filter:drop-shadow(0 2px 6px rgba(0,0,0,.85))}
/* the same white highlight trips use, applied to travellers */
.permark .face,.airmark .plane,.permark .pulse,.airmark .ring{transition:border-color .2s ease,box-shadow .2s ease,filter .2s ease}
.permark.lit .face{border-color:#fff;box-shadow:0 0 0 3px rgba(255,255,255,.4),0 2px 12px rgba(0,0,0,.85)}
.permark.lit .pulse,.airmark.lit .ring{border-color:#fff;opacity:.85}
.airmark.lit .plane{filter:drop-shadow(0 0 4px rgba(255,255,255,.9)) drop-shadow(0 2px 6px rgba(0,0,0,.85))}

/* the traveller's own page */
.privrow{display:flex;align-items:center;justify-content:center;gap:9px;flex-wrap:wrap;margin-top:18px}
.privrow .addtrip{width:auto;margin-top:0}
/* paste a trip */
.whybox{display:flex;flex-direction:column;gap:9px;margin-bottom:14px}
.why{display:flex;gap:10px;font-size:12.5px;color:var(--dim);line-height:1.5}
.why b{color:var(--ink);font-weight:700}
/* "Either / Or" rather than 1 and 2, which read as steps */
.whyhead{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);margin-bottom:4px}
.whyn{flex-shrink:0;min-width:46px;padding:2px 8px;height:20px;border-radius:99px;background:rgba(108,140,255,.18);color:var(--accent2);font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;display:flex;align-items:center;justify-content:center}
/* a picture of the button they're being told to press */
.demobtn{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--hair2);background:rgba(255,255,255,.05);border-radius:99px;padding:1px 8px;font-size:11px;font-weight:600;color:var(--ink);white-space:nowrap;vertical-align:1px}
.demobtn.blue{border-color:rgba(108,140,255,.45);color:var(--accent2)}
.demobtn svg{display:block}
.sbbtn.accentblue{border-color:rgba(108,140,255,.5);color:var(--accent2);gap:7px}
.sbbtn.accentblue:hover{background:rgba(108,140,255,.14);border-color:var(--accent)}
.fmtbox{margin-top:18px;border-top:1px solid var(--hair);padding-top:12px}
.fmtbox pre{font-family:var(--mono);font-size:10.5px;color:var(--dim);background:rgba(0,0,0,.32);border-radius:9px;padding:10px;margin:8px 0;overflow-x:auto;white-space:pre;line-height:1.65}
/* a fold-away section, styled like everything else rather than a browser default */
/* <details> can't animate its own height, so this is a div that can */
.foldbox{border:1px solid var(--hair);border-radius:12px;background:rgba(255,255,255,.02);padding:0 11px;margin-bottom:11px;overflow:hidden}
.foldhead{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;border:0;background:none;cursor:pointer;padding:10px 0;font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);text-align:left}
.foldhead:hover{color:var(--ink)}
.foldhead svg{transition:transform .28s cubic-bezier(.4,0,.2,1);flex-shrink:0}
.foldbox.open .foldhead svg{transform:rotate(180deg)}
.foldbody{max-height:0;opacity:0;overflow:hidden;transition:max-height .3s cubic-bezier(.4,0,.2,1),opacity .22s ease}
.foldbox.open .foldbody{max-height:180px;opacity:1}
.foldbox.open .foldhead{border-bottom:1px solid var(--hair)}
.foldinner{padding:11px 0 9px}
.foldinner .phint{margin-top:6px}
/* an empty hint still occupied a line under the input */
.foldinner .phint:empty{display:none}
.foldbox .promorow:last-child{margin-bottom:0}
.contactbox{margin-top:20px;border-top:1px solid var(--hair);padding-top:14px}
/* the shared label style is green, which read oddly down here */
.contactlbl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);margin-bottom:6px}
.contactbox p{font-size:12px;color:var(--dim);line-height:1.5;margin:0 0 9px}
.contactbox p b{color:var(--ink)}
.contactbox .sbbtn{text-decoration:none;justify-content:center;gap:7px}
.sharebox{text-align:center;padding:26px 6px 6px}
.sharebox h2{font-family:var(--disp);font-size:23px;font-weight:800;letter-spacing:-0.025em;margin:0 0 8px}
.sharesub{font-size:13px;color:var(--dim);margin:0 0 20px;min-height:19px}
.sharenote{font-size:11.5px;color:var(--dim);margin-top:16px;line-height:1.5;text-align:left;border-top:1px solid var(--hair);padding-top:12px}
.otbox{margin-top:14px;border:1px solid rgba(255,211,77,.3);background:rgba(255,211,77,.06);border-radius:12px;padding:12px;text-align:left}
.otlbl{font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--stay);margin-bottom:6px}
.otp{font-size:11.5px;color:var(--dim);line-height:1.55;margin:0 0 9px}
.otp b{color:var(--ink)}
.otbox .pslink{margin-bottom:8px}
.otbox .copyspace{width:100%}

/* new-trip button pinned to the top of the panel on every view */
/* A row of pinned buttons. Track and Inspo put one button in it and it takes
   the whole width; Plan puts two in and they share it. The two-column split
   belongs to the pair, not to the row, or a lone button ends up half width. */
.pinrow{margin:0 0 12px;display:grid;grid-template-columns:1fr;gap:8px}
.pinrow.pair{grid-template-columns:1fr 1fr}
.pinrow .half{width:100%;margin:0;min-width:0}
/* Colour of its own, so it reads as the other way to start rather than a
   greyed-out version of the first. Mint against the button beside it, which is
   blue through violet: related, clearly not the same. */
.importbtn{position:relative;overflow:hidden;
  display:flex;align-items:center;justify-content:center;gap:8px;
  border:1px solid color-mix(in srgb,var(--ok) 40%,transparent);border-radius:13px;
  padding:13px 14px;color:var(--ok);
  background:linear-gradient(135deg,color-mix(in srgb,var(--ok) 16%,transparent),
                                   color-mix(in srgb,var(--fly) 10%,transparent));
  font-family:var(--disp);font-weight:700;font-size:14px;letter-spacing:-.01em;
  cursor:pointer;white-space:nowrap;
  transition:border-color .16s ease,background .16s ease,color .16s ease,transform .16s ease}
.importbtn:hover{border-color:var(--ok);transform:translateY(-1px);
  background:linear-gradient(135deg,color-mix(in srgb,var(--ok) 26%,transparent),
                                   color-mix(in srgb,var(--fly) 16%,transparent))}
@supports not (color:color-mix(in srgb,red 50%,transparent)){
  .importbtn{border-color:rgba(95,227,176,.4);background:rgba(95,227,176,.14);color:var(--ok)}
}
/* Locked: visibly not available, but still pressable, because pressing it is
   how someone finds out what it is. */
/* Locked: the colour drains out, so what is available and what is not can be
   told apart at a glance. Still pressable, because pressing it is how someone
   finds out what it is. */
.importbtn.locked{color:var(--dim);border-color:var(--hair2);border-style:dashed;
  background:rgba(255,255,255,.015);transform:none}
.importbtn.locked:hover{color:var(--ink);border-color:var(--accent2);border-style:solid;
  background:rgba(108,140,255,.1);transform:none}
@media (max-width:380px){
  /* two of these will not fit side by side legibly on the smallest screens */
  .pinrow.pair{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){.importbtn{transition:none}}
.pinrow .addtrip{margin-top:0}
.pasterow{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;margin-top:7px;border:0;background:none;color:var(--dim);font-size:11.5px;font-weight:600;cursor:pointer;padding:2px}
.pasterow:hover{color:var(--ink)}
.pfield textarea{width:100%;border:1px solid var(--hair2);border-radius:9px;padding:9px 10px;background:rgba(0,0,0,.3);color:var(--ink);font-family:var(--mono);font-size:11.5px;line-height:1.6;resize:vertical}
.pfield textarea:focus{outline:none;border-color:var(--accent)}
.impex{margin-top:14px;border:1px solid var(--hair);border-radius:11px;padding:10px 12px;background:rgba(255,255,255,.02)}
.impex summary{cursor:pointer;font-size:12px;font-weight:600;color:var(--dim)}
.impex summary:hover{color:var(--ink)}
.impex pre{font-family:var(--mono);font-size:11px;color:var(--ink);background:rgba(0,0,0,.32);border-radius:8px;padding:9px 10px;margin:9px 0;overflow-x:auto;white-space:pre-wrap;line-height:1.6}

.acctbar{display:flex;align-items:center;gap:9px;border:1px solid var(--hair2);background:rgba(255,255,255,.04);border-radius:12px;padding:9px 10px;margin-bottom:10px;font-size:12px;color:var(--dim);animation:rise .3s ease}
/* Already arrived: a later render puts it back in place without replaying the
   entrance, which otherwise reads as the notice loading twice. */
.acctbar.settled{animation:none}
.acctbar.warn{border-color:rgba(255,138,77,.45);background:rgba(255,138,77,.09)}
.acctbar.stop{border-color:rgba(255,122,107,.5);background:rgba(255,122,107,.1)}
.bartxt{flex:1;line-height:1.45}
.bartxt b{color:var(--ink)}
.barbtn{display:inline-flex;align-items:center;gap:6px;border:0;border-radius:9px;padding:6px 11px;background:#fff;color:#1B2430;font-size:11.5px;font-weight:700;cursor:pointer;white-space:nowrap;flex-shrink:0}
.barbtn:hover{filter:brightness(.95)}
.barx{border:0;background:none;color:var(--dim);font-size:12px;cursor:pointer;padding:2px 4px;flex-shrink:0}
.barx:hover{color:var(--ink)}
.selbar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;border:1px solid rgba(108,140,255,.4);background:rgba(108,140,255,.08);border-radius:12px;padding:8px 10px;margin-bottom:10px;font-size:12px;color:var(--dim)}
.selbar .cnt{display:inline-flex;align-items:baseline;gap:4px;color:var(--ink);font-weight:600}
.selbar .cnt b{font-size:13.5px;font-weight:800;line-height:1}
.selbar .sp{flex:1}
.selbar button{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--hair2);background:none;color:var(--ink);border-radius:8px;padding:5px 11px;font-size:11.5px;font-weight:600;cursor:pointer}
.selbar button:hover{border-color:rgba(108,140,255,.6)}
.selbar button.danger{color:var(--err);border-color:rgba(255,122,107,.4)}
.selbar button[disabled]{opacity:.35;cursor:default}

/* Each trip already has a colour, and it was doing nothing but tinting a 5px
   bar. Here it belongs to the whole card: it bleeds off the spine into the
   surface, warms the border, and is what answers the pointer. The base stays
   the same glass as everything else, so the colour is the only thing setting
   one card apart from the next. */
.tripcard{--tc:var(--accent2);position:relative;overflow:hidden;
  display:flex;gap:8px;align-items:center;border:1px solid var(--hair);background:var(--glass2);border-radius:14px;padding:12px 8px 12px 0;margin-bottom:10px;cursor:pointer;transition:border-color .15s,transform .15s,outline-color .25s ease;animation:rise .3s ease;overflow:hidden;outline:2px solid transparent;outline-offset:-1px}
/* The trip's own colour answers the pointer, rather than one blue for all.
   Pointing at the card and pointing at its line on the map are the same
   gesture, so they get the same answer: hovering a line adds .hl, and .hl and
   :hover are styled as one thing. The card used to answer a line with nothing
   but a white outline. */
.tripcard:hover,.tripcard.hl{border-color:color-mix(in srgb,var(--tc) 50%,transparent);
  transform:translateY(-1px);box-shadow:0 10px 26px -14px var(--tc)}
@supports not (color:color-mix(in srgb,red 50%,transparent)){
  .tripcard:hover,.tripcard.hl{border-color:rgba(255,255,255,.2)}
}
/* The outline stays: it is what tells the two apart when the pointer is on the
   map rather than the card. */
.tripcard.hl{outline-color:#fff}
/* Two washes of the trip's colour: one bleeding off the spine across the card,
   one blooming from the top-left corner. Both behind the content, neither
   reaching the right-hand side, so nothing ever sits on colour it has to be
   read against. */
/* Carries the card's corners itself rather than trusting the clip, for the
   same reason the stats card does. */
.tripcard:before{content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:
    radial-gradient(90% 130% at 0% 0%,var(--tc),transparent 55%),
    linear-gradient(90deg,var(--tc),transparent 46%);
  opacity:.11;transition:opacity .22s ease}
.tripcard:hover:before,.tripcard.hl:before{opacity:.2}
/* A hairline of the colour along the bottom, so a card has a base as well as
   an edge. It draws itself in from the spine when you point at it. */
.tripcard:after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,var(--tc),transparent 70%);
  opacity:0;transform:scaleX(.3);transform-origin:left;
  transition:opacity .25s ease,transform .35s cubic-bezier(.22,.61,.36,1)}
.tripcard:hover:after,.tripcard.hl:after{opacity:.55;transform:none}
.tripcard>*{position:relative}
/* The spine fades out towards the bottom rather than sitting as a solid block,
   and lights up when the card is pointed at. */
.tripcard .bar{width:5px;align-self:stretch;border-radius:0 3px 3px 0;flex-shrink:0;
  background:linear-gradient(180deg,var(--tc),color-mix(in srgb,var(--tc) 35%,transparent));
  box-shadow:0 0 14px -3px var(--tc);
  transition:width .2s cubic-bezier(.22,.61,.36,1),box-shadow .2s ease}
.tripcard:hover .bar,.tripcard.hl .bar{width:8px;box-shadow:0 0 20px -2px var(--tc)}
@supports not (color:color-mix(in srgb,red 50%,transparent)){
  .tripcard .bar{background:var(--tc)}
}
.tripcard .tbody{flex:1;min-width:0;padding-left:5px}
.tripcard .tname{font-family:var(--disp);font-weight:700;font-size:16px;letter-spacing:-0.015em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tripcard .troute{font-family:var(--mono);font-size:11.5px;color:var(--ink);opacity:.82;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.tripcard .tmeta{font-size:11.5px;color:var(--dim);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tripcard .soon{color:var(--accent2);font-weight:600}
.tripcard .allbkd{color:var(--ok);font-weight:700}
.tickbox{width:22px;height:22px;border-radius:7px;border:2px solid var(--hair2);flex-shrink:0;margin-right:6px;display:flex;align-items:center;justify-content:center;font-size:13px;color:transparent}
.tripcard.sel .tickbox{background:var(--accent);border-color:var(--accent);color:#070B18}
.tripcard.sel{border-color:rgba(108,140,255,.7)}
.iconbtn{border:0;background:none;color:var(--dim);cursor:pointer;font-size:15px;line-height:1;padding:7px 9px;border-radius:9px;flex-shrink:0}
.iconbtn:hover{background:rgba(255,255,255,.08);color:var(--ink)}
.iconbtn[disabled]{opacity:.22;cursor:default}
.iconbtn[disabled]:hover{background:none;color:var(--dim)}
.tripcard .iconbtn{width:42px;height:42px;padding:0;display:flex;align-items:center;justify-content:center}

.edithead{display:flex;align-items:center;gap:6px;margin-bottom:10px}
.nwrap{display:flex;align-items:center;gap:3px;flex:1;min-width:0;border-bottom:1px dashed var(--hair2);padding-bottom:2px}
.nwrap:hover,.nwrap:focus-within{border-bottom-color:var(--accent2)}
.namein{flex:1;min-width:0;border:0;background:none;color:var(--ink);font-family:var(--disp);font-weight:700;font-size:19px;letter-spacing:-0.02em;padding:4px 2px;text-overflow:ellipsis}
.namein:focus{outline:none}
.penbtn{border:0;background:none;color:var(--dim);cursor:pointer;padding:3px;line-height:0;flex-shrink:0}
.penbtn:hover{color:var(--accent2)}
.vlbtn{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--hair2);background:rgba(255,255,255,.04);color:var(--ink);border-radius:99px;padding:5px 11px;font-size:11.5px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0}
.vlbtn:hover{border-color:rgba(108,140,255,.55);color:var(--accent2)}
.vlbtn.track:hover{border-color:rgba(255,211,77,.6);color:var(--stay)}

/* speedy booking */
.qb{position:relative;border:1px solid rgba(255,255,255,.16);border-radius:12px;margin-bottom:10px;overflow:hidden;background:linear-gradient(103deg,rgba(127,200,255,.20) 0%,rgba(255,211,77,.15) 52%,rgba(255,138,77,.20) 100%)}
.qb:before{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,14,21,.30),rgba(10,14,21,.62));pointer-events:none}
.qb>*{position:relative}
.qbhead{display:flex;align-items:center;gap:8px;width:100%;border:0;background:none;padding:10px 12px;cursor:pointer;text-align:left}
.qbhead:hover{background:rgba(255,255,255,.06)}
.qbt{font-family:var(--disp);font-size:13.5px;font-weight:800;letter-spacing:-0.01em;display:flex;align-items:center;gap:7px}
.qbicons{display:inline-flex;align-items:center;gap:4px}
/* each icon lifts out of greyscale in turn on a 2s loop: plane → house → car */
.qbicons i{display:inline-flex;line-height:0;filter:grayscale(1);opacity:.45;animation:qbflash 2s linear infinite}
.qbicons i:nth-child(2){animation-delay:.4s}
.qbicons i:nth-child(3){animation-delay:.8s}
@keyframes qbflash{
  0%{filter:grayscale(1);opacity:.45}
  4%{filter:grayscale(0);opacity:1}
  16%{filter:grayscale(0);opacity:1}
  22%{filter:grayscale(1);opacity:.45}
  100%{filter:grayscale(1);opacity:.45}
}
@media (prefers-reduced-motion:reduce){.qbicons i{filter:none;opacity:1}}
.qbchev{color:var(--dim);font-size:23px;line-height:1;transition:transform .2s;flex-shrink:0;margin-left:auto}
.qb.open .qbchev{transform:rotate(180deg)}
.qbbody{max-height:0;opacity:0;overflow:hidden;padding:0 12px;transition:max-height .32s cubic-bezier(.4,0,.2,1),opacity .22s ease,padding-bottom .32s ease}
.qb.open .qbbody{max-height:900px;opacity:1;padding-bottom:12px}
.paxrow{display:flex;gap:3px;align-items:center;margin-bottom:9px;flex-wrap:wrap}
.paxbtn{border:0;background:none;padding:2px;cursor:pointer;line-height:0;opacity:.28;transition:opacity .15s,transform .15s}
.paxbtn.on{opacity:1}
.paxbtn:hover{transform:translateY(-1px)}
.paxn{font-size:11px;color:var(--dim);margin-left:6px;font-weight:600;white-space:nowrap}
.srow{display:flex;gap:6px;align-items:flex-end;margin-bottom:2px}
.sfield{flex:1;min-width:0}
.slbl{font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);display:block;margin-bottom:2px}
.ssel{width:100%;border:1px solid var(--hair2);background:rgba(0,0,0,.3);color:var(--ink);border-radius:8px;padding:4px 7px;font-size:12px;font-weight:600;cursor:pointer}
.gobtn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;margin-top:6px;border:1px solid rgba(127,200,255,.45);background:rgba(127,200,255,.1);color:var(--fly);border-radius:9px;padding:6px 10px;font-size:12px;font-weight:700;text-decoration:none;white-space:nowrap}
.gobtn:hover{background:rgba(127,200,255,.18)}
.gobtn.stay{border-color:rgba(255,211,77,.45);background:rgba(255,211,77,.1);color:var(--stay)}
.gobtn.stay:hover{background:rgba(255,211,77,.18)}
.gobtn.car{border-color:rgba(255,138,77,.45);background:rgba(255,138,77,.1);color:var(--drv)}
.gobtn.car:hover{background:rgba(255,138,77,.18)}
.qbnote{font-size:10px;color:var(--dim);margin-top:5px;text-align:center}
.qbsplit{margin-top:9px;padding-top:9px;border-top:1px solid var(--hair)}

.allbkdbtn{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;border:1px solid var(--hair2);background:rgba(255,255,255,.02);color:var(--dim);border-radius:10px;padding:7px 12px;font-size:12px;font-weight:600;cursor:pointer;margin-bottom:10px}
.allbkdbtn:hover{color:var(--ink)}
.allbkdbtn.on{background:rgba(95,227,176,.14);border-color:var(--ok);color:var(--ok)}

.emptycards{border:1px dashed var(--hair2);border-radius:12px;padding:22px 14px;text-align:center;font-size:12.5px;color:var(--dim);margin-bottom:10px}
.emptycards[hidden]{display:none}

/* The same language as the trip cards, in the mode's colour rather than the
   trip's: the edge it is already named by, a wash off that edge, a bloom in
   the corner, and a hairline underneath that draws itself in. */
.legcard{--mc:var(--fly);position:relative;overflow:hidden;
  border:1px solid var(--hair);background:var(--glass2);
  border-left:3px solid var(--mc);border-radius:12px;padding:8px 10px;cursor:pointer;
  box-shadow:0 0 0 0 transparent;
  transition:border-color .2s ease,box-shadow .22s ease}
.legcard:hover{border-color:color-mix(in srgb,var(--mc) 42%,transparent);
  box-shadow:0 8px 22px -16px var(--mc)}
@supports not (color:color-mix(in srgb,red 50%,transparent)){
  .legcard:hover{border-color:var(--hair2)}
}
.legcard:after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,var(--mc),transparent 70%);
  opacity:0;transform:scaleX(.3);transform-origin:left;
  transition:opacity .25s ease,transform .35s cubic-bezier(.22,.61,.36,1)}
.legcard:hover:after,.legcard.open:after{opacity:.5;transform:none}
.legcard.fresh{animation:rise .25s ease}
.legcard:before{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:
    radial-gradient(85% 120% at 0% 0%,var(--mc),transparent 55%),
    linear-gradient(180deg,var(--mc),transparent 46%);
  opacity:.08;transition:opacity .22s ease}
.legcard:hover:before,.legcard.open:before{opacity:.14}
.legcard>*{position:relative}
.legcard.drive{--mc:var(--drv)}
.legcard.rail{--mc:var(--rail)}
.legcard.boat{--mc:var(--boat)}
.legcard.stop{--mc:var(--stay);border-left-style:dashed;border-color:rgba(255,211,77,.22);border-left-color:var(--mc)}
.legcard .leghead{display:flex;align-items:center;gap:1px;margin-bottom:6px}
.movebtns{display:inline-flex;gap:0;margin-right:1px;flex-shrink:0}
.movebtns .iconbtn{padding:5px 5px;font-size:10px}
.leghead .iconbtn{padding:7px 8px;font-size:14px}
.legcard .ln{display:inline-flex;align-items:center;gap:5px;margin-right:auto;font-family:var(--disp);font-size:10px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--mc);background:rgba(255,255,255,.05);border:1px solid var(--hair);border-radius:99px;padding:2px 9px}
.mode{display:inline-flex;border:1px solid var(--hair);border-radius:9px;overflow:hidden;background:rgba(0,0,0,.25);flex-shrink:0}
.mode button{border:0;background:none;padding:5px 7px;cursor:pointer;line-height:0;color:var(--dim);opacity:.5;transition:all .12s}
.mode button:hover{opacity:.8}
.mode button.on{background:rgba(255,255,255,.14);color:var(--mc);opacity:1;box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.mode.words button{font-size:11px;font-weight:700;letter-spacing:.02em;padding:4px 11px;line-height:1.3}
.mode.words button.on{background:rgba(255,211,77,.2);color:var(--stay)}
.legcard /* From, the swap, To, then the date. The date column is sized to the width of
   dd/mm/yyyy and no more, which is what pays for the swap button; the two ends
   give up the rest between them equally. */
/* Cells stretch to the tallest, so the swap cell is exactly as tall as a field
   beside it. Its empty label takes the same height as their labels, and the
   button fills what remains — which is precisely the height of an input, with
   no number written down anywhere. */
.grid{display:grid;grid-template-columns:1fr 26px 1fr 104px;gap:5px;align-items:stretch}
/* No container: just the glyph, sitting level with the middle of the inputs
   beside it. The cell is a field like its neighbours, so the empty label above
   pushes it down by exactly the height of their labels, and the button then
   fills what is left. Nothing here is a chosen number. */
.field.swapfield{min-width:0}
.field.swapfield label{display:block}
.field.swapfield{display:flex;flex-direction:column}
.field .sw{flex:1;display:flex;align-items:center;justify-content:center;
  width:100%;padding:0;border:0;background:none;cursor:pointer;user-select:none;
  color:var(--dim);font-size:15px;line-height:1;
  transition:color .15s ease,transform .15s ease}
.field .sw:hover{color:var(--accent2);transform:scale(1.12)}
.field .sw:active{transform:scale(.96)}
.grid input[type=date]{min-width:0;padding-left:8px;padding-right:6px}
/* A stop has one place, so there are no ends to swap. */
/* A stop's first line: the place at 40%, and the dates sharing what is left.
   Auto columns rather than a fixed count, because a stay shows check-in and
   check-out while a place shows only the day — and the hidden fields between
   them take no space, so the count varies. */
.legcard.stop .grid{grid-auto-flow:column;grid-template-columns:40%;grid-auto-columns:1fr}
.legcard.stop .grid .swapfield{display:none!important}
.field[hidden]{display:none!important}
.field{position:relative;min-width:0}
.field label{display:block;font-size:9px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--dim);margin-bottom:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* slimmer inputs across every card */
/* Back to sizing by padding, as before. The one thing that stays is an
   explicit line-height: with the same padding, border and font, a select and a
   text input still differed because each browser picks its own line-height for
   a select. Stating it makes their content boxes identical, which is what the
   cabin class box needed. */
.field input,.field textarea,.field select{width:100%;min-width:0;border:1px solid var(--hair2);border-radius:8px;padding:4px 7px;background:rgba(0,0,0,.3);color:var(--ink);font-size:12.5px;line-height:1.35;transition:border-color .15s}
.field textarea{line-height:1.5}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--mc);outline:none}
.field select{cursor:pointer}
.field input.o,.field input.d{font-family:var(--mono);text-transform:uppercase}
.legcard.drive .field input.o,.legcard.drive .field input.d,.legcard.rail .field input.o,.legcard.rail .field input.d,.legcard.boat .field input.o,.legcard.boat .field input.d,.legcard.stop .field input.o{font-family:var(--font);text-transform:none}
.field input.bl{font-size:11.5px}
.legcard.fly .field input.fn{text-transform:uppercase}
.field input[type=date],.field input[type=time]{color-scheme:dark;font-family:var(--font);font-size:11.5px;padding:4px 4px}
.ac{position:fixed;z-index:900;background:rgba(16,21,30,.98);border:1px solid var(--hair2);border-radius:12px;box-shadow:0 18px 46px rgba(0,0,0,.7);display:none;max-height:250px;overflow-y:auto;overscroll-behavior:contain;backdrop-filter:blur(8px)}
.ac-item{padding:7px 12px;font-size:12.5px;cursor:pointer;display:flex;gap:8px;align-items:baseline}
.ac-item:hover,.ac-item.hi{background:rgba(108,140,255,.14)}
.ac-item b{font-family:var(--mono);font-size:12px;color:var(--accent2);flex-shrink:0}
.ac-item .t{color:var(--dim);font-size:11px;margin-left:auto;white-space:nowrap;padding-left:6px}
.ac-item .near{color:var(--accent2)}
.ac-item .stn{color:var(--rail)}
.ac-item.dim{color:var(--dim);cursor:default}
.ac-item.pindrop{display:flex;align-items:center;gap:9px;color:var(--stay);font-weight:500;border-bottom:1px solid var(--hair);background:rgba(255,211,77,.07);padding:9px 12px}
.ac-item.pindrop .pico{display:inline-flex;align-items:center;line-height:0;flex-shrink:0}
.ac-item.pindrop b{font-family:inherit;font-size:inherit;color:var(--stay);font-weight:800}
.ac-item.pindrop:hover{background:rgba(255,211,77,.17)}
.pinbar{position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:900;display:flex;align-items:center;gap:12px;background:rgba(12,17,25,.96);border:2.5px solid var(--stay);color:var(--stay);border-radius:99px;padding:9px 9px 9px 18px;font-size:14px;font-weight:800;letter-spacing:-0.01em;backdrop-filter:blur(8px);box-shadow:0 0 0 4px rgba(255,211,77,.13),0 12px 38px rgba(0,0,0,.6)}
.pinbar[hidden]{display:none}
.pinbar button{border:1px solid rgba(255,211,77,.45);background:rgba(255,211,77,.1);color:var(--stay);border-radius:99px;padding:5px 14px;font-size:12px;font-weight:700;cursor:pointer}
.pinbar button:hover{background:rgba(255,211,77,.2)}
body.pinning #map,body.pinning .leaflet-grab{cursor:crosshair}
/* while pinning, the map is the only thing you can interact with */
body.pinning .col,body.pinning .col *,body.pinning .spacebox,body.pinning .spacebox *,body.pinning .ac,body.pinning .leaflet-control-attribution{pointer-events:none!important}
body.pinning .col,body.pinning .spacebox{opacity:0;visibility:hidden;transition:opacity .18s ease,visibility 0s linear .18s}

/* The summary takes the space it needs and the booking link sits at the end of
   it, dropping to its own line only when there is genuinely no room. */
.cstat{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-top:6px;
  font-size:11.5px;line-height:1.55;color:var(--dim);font-variant-numeric:tabular-nums}
.cstat .nums{flex:1 1 auto;min-width:0}
.cstat .spacer{display:none}
.cstat /* Plain inline text, not a flex row. As a wrapping flex container each piece
   was its own item, so a long summary broke after the first item and left the
   rest of the line empty. As text it fills each line before wrapping. */
.nums{display:inline;line-height:1.55}
.cstat .big{font-size:13px;font-weight:800;color:var(--mc);letter-spacing:-0.01em}
.cstat .spacer{flex:1}
.cstat a{border:1px solid var(--hair);border-radius:99px;padding:3px 10px;font-size:10.5px;color:var(--dim);text-decoration:none;background:rgba(255,255,255,.02);white-space:nowrap}
.cstat a:hover{color:var(--mc);border-color:var(--mc)}
.cstat a.prime{border-color:var(--mc);color:var(--mc);background:rgba(255,255,255,.06);font-weight:700}
.noteline{font-size:11.5px;color:var(--dim);font-style:italic;margin-top:5px;white-space:pre-wrap}
.cardrow{display:flex;align-items:center;gap:6px;margin-top:7px;flex-wrap:wrap}
.bkdbtn{border:1px solid var(--hair2);background:none;color:var(--dim);border-radius:99px;padding:4px 12px;font-size:11.5px;font-weight:600;cursor:pointer;white-space:nowrap}
.bkdbtn:hover{color:var(--ink)}
.bkdbtn.on{background:rgba(95,227,176,.16);border-color:var(--ok);color:var(--ok)}
.detbtn{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--hair2);background:rgba(255,255,255,.03);color:var(--dim);border-radius:99px;padding:4px 12px 4px 14px;font-size:11.5px;font-weight:600;cursor:pointer;margin-left:auto}
.dchev{font-size:11px;line-height:1;transition:transform .18s}
.detbtn.open .dchev{transform:rotate(180deg)}
.detbtn:hover{color:var(--ink);border-color:var(--hair2)}
.details{display:grid;grid-template-columns:1fr 1fr;gap:5px;max-height:0;opacity:0;overflow:hidden;margin-top:0;transition:max-height .3s cubic-bezier(.4,0,.2,1),opacity .2s ease,margin-top .3s ease}
.details.open{max-height:640px;opacity:1;margin-top:7px}
.details .full{grid-column:1/-1}
/* The booking reference, and on a stop the cost beside it. Two short fields on
   one line rather than two rows each half empty. */
/* The fields that get filled in together, side by side and always equal: the
   reference and the cost on a stop; the time and the reference on a flight;
   the time, the reference and the cost on anything else. However many there
   are, they share the line. */
.refrow{grid-column:1/-1;display:grid;gap:5px;grid-auto-flow:column;grid-auto-columns:1fr}
.trio{grid-column:1/-1;display:grid;gap:5px;grid-template-columns:repeat(auto-fit,minmax(86px,1fr))}
.details textarea{resize:vertical;min-height:34px}

/* the slim insert row lives between cards — the bottom add row matches it exactly */
/* locked by its owner: hide every control that would change something, rather
   than letting someone edit and only find out when it doesn't save */
body.readonly .pinrow,body.readonly .addrow,body.readonly .insrow,body.readonly .allbkdbtn,
body.readonly .tripcard .iconbtn,body.readonly .leghead .iconbtn,body.readonly .movebtns,
body.readonly .mode,body.readonly .bkdbtn,body.readonly #selBtn{display:none!important}
body.readonly .field input,body.readonly .field textarea,body.readonly .field select,
body.readonly .namein,body.readonly .pfield input{pointer-events:none;opacity:.8}
.insrow,.addrow{display:flex;gap:6px;justify-content:center;padding:3px 0;opacity:.45;transition:opacity .15s}
.insrow:hover,.addrow:hover{opacity:1}
.slimbtn{border:1px dashed var(--hair2);background:none;color:var(--dim);border-radius:99px;padding:1px 14px;font-size:10.5px;font-weight:700;cursor:pointer;line-height:1.6}
.slimbtn:hover{color:var(--ink);border-color:var(--hair2)}
.slimbtn.st:hover{color:var(--stay);border-color:rgba(255,211,77,.5)}
.slimbtn[disabled]{opacity:.4;cursor:default}

.vhead{margin-bottom:14px}
.vtitle{font-family:var(--disp);font-size:23px;font-weight:800;letter-spacing:-0.025em;line-height:1.15}
.vsub{font-size:12.5px;color:var(--dim);margin-top:4px}
.vsub .soon{color:var(--accent2);font-weight:600}
.vrow{--mc:var(--fly);position:relative;border:1px solid var(--hair);border-left:3px solid var(--mc);border-radius:11px;background:var(--glass2);padding:9px 11px;margin-bottom:7px;overflow:hidden}
.vrow:before{content:'';position:absolute;inset:0;border-radius:inherit;background:linear-gradient(180deg,var(--mc),transparent 46%);opacity:.06;pointer-events:none}
.vrow>*{position:relative}
.vrow.drive{--mc:var(--drv)}
.vrow.rail{--mc:var(--rail)}
.vrow.boat{--mc:var(--boat)}
.vrow.stop{--mc:var(--stay);border-left-style:dashed}
.vdate{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--mc);display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.vdate .bkd{color:var(--ok)}
.vmain{font-family:var(--mono);font-size:15px;font-weight:700;margin-top:3px}
.vrow.drive .vmain,.vrow.rail .vmain,.vrow.stop .vmain{font-family:var(--disp);font-size:14.5px;letter-spacing:-0.01em}
.vmeta{font-size:11.5px;color:var(--dim);margin-top:2px}
.vnote{font-size:11px;color:var(--dim);font-style:italic;margin-top:5px;white-space:pre-wrap}
.vlink{margin-top:7px}
.vlink a{display:inline-block;border:1px solid var(--mc);color:var(--mc);background:rgba(255,255,255,.05);border-radius:99px;padding:3px 12px;font-size:11.5px;font-weight:700;text-decoration:none}
.cta{margin-top:16px;border:1px solid rgba(108,140,255,.3);background:linear-gradient(180deg,rgba(108,140,255,.12),rgba(108,140,255,.04));border-radius:14px;padding:16px;text-align:center}
.cta h3{font-family:var(--disp);font-size:16px;margin:0 0 4px;letter-spacing:-0.01em}
.cta p{font-size:12.5px;color:var(--dim);margin:0 0 12px}
.roflag{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);border:1px solid var(--hair2);border-radius:99px;padding:2px 9px;margin-bottom:10px}

@media (max-width:760px){
  .col{left:0;right:0;top:auto;bottom:0;width:auto;max-height:52vh;padding:0 10px calc(8px + env(safe-area-inset-bottom));gap:7px}
  .brandbar{border-radius:12px;padding:9px 11px;cursor:pointer}
  .brandbar h1{font-size:16px}
  .sheet{border-radius:16px;padding:13px 10px 13px 13px;max-height:44vh;transition:max-height .3s ease,padding .3s ease,opacity .25s ease,border-width .3s ease}
  .totalchip{transition:max-height .3s ease,padding .3s ease,opacity .25s ease,border-width .3s ease;overflow:hidden;max-height:90px}
  body.sheetmin .col{max-height:none;gap:0}
  body.sheetmin .sheetwrap{flex:0 0 auto;box-shadow:none}
  body.sheetmin .sheet{max-height:0;padding-top:0;padding-bottom:0;opacity:0;overflow:hidden;border-width:0;box-shadow:none}
  body.sheetmin .totalchip{max-height:0;padding-top:0;padding-bottom:0;opacity:0;border-width:0;margin:0}
  body.sheetmin .topbtn,body.sheetmin .hgroup{display:none}
  /* the panel owns the bottom of the screen on mobile, so the toast sits up top */
  .toast{bottom:auto;top:12px;right:12px;left:12px;justify-content:center}
  .pinbar{top:12px;left:12px;right:12px;transform:none;justify-content:space-between;font-size:13px;padding:9px 9px 9px 14px}
  /* the toast also lives up top on mobile, so move it clear of the pin notice */
  body.pinning .toast{top:70px}
  .brandbar{flex-wrap:wrap;row-gap:6px}
  .topbtn.cta-own{padding:5px 11px;font-size:11.5px}
  .pinrow{margin-bottom:10px}
  /* The corner card is hidden on a phone, except when it is the sliding panel
     at the top — which is the same element, repositioned. Last time this rule
     hid it no matter what class it carried, so the panel was styled, moved and
     never displayed. */
  /* an empty sheet under the wordmark is worse than no sheet at all */
  body.booting .sheetwrap,body.booting .totalchip{display:none}
  /* On a phone the corner panel does not exist at all; only the sliding one
     does. Stated with !important because the rule above keeps a hidden panel
     displayed so it can animate. */
  .spacebox{display:none!important}
  .spacebox.drop{display:block!important}
  .spacebox.inline{display:block}
  /* four modes plus the row of icon buttons is tight on a phone */
  .leghead{flex-wrap:wrap;row-gap:4px}
  .leghead .iconbtn{padding:6px 6px;font-size:13px}
  .mode button{padding:5px 6px}
  /* narrow: the two ends and the swap share the first row, the date takes the
     second. The swap is between them here too, which is the point of it. */
  .legcard .grid{grid-template-columns:1fr 26px 1fr}
  .legcard .grid .field:nth-child(4){grid-column:1/-1}
  .legcard .grid .cofield{grid-column:1/-1}
  /* too narrow to put a hotel name and two dates on one line */
  .legcard.stop .grid{grid-auto-flow:row;grid-template-columns:1fr 1fr}
  .legcard.stop .grid .field:first-child{grid-column:1/-1}
  .insrow,.addrow{opacity:1}
  .field input{font-size:16px}
  .field textarea{font-size:16px}
  .field input[type=date],.field input[type=time]{font-size:13px}
  .ac{min-width:0;right:0}
  .hero{padding:24px 8px 4px}
  .hero.tucked{padding-top:18px}
  .hero h2{font-size:22px}
  .hero p{font-size:12.5px}
  .hero .mark{width:42px;height:42px;margin-bottom:14px}
}
