/* styles-c.css -- SHIPMENT TRACKER
   ------------------------------------------------------------------
   THIRD stylesheet, opened 2026-08-04. styles.css was 68,028 bytes and
   styles-b.css was 68,518 against a 70,000-byte hard limit, so there was
   no room left in either. DEPLOY_RULES.md says split BEFORE the limit,
   not after truncation proves the point again -- styles.css was silently
   truncated in production three separate times.
   Keep this file small. When it approaches 70,000, open styles-d.css.
   ------------------------------------------------------------------ */

/* ==================================================================
   BACK BUTTON CLEARANCE
   ------------------------------------------------------------------
   Found 2026-08-20 by measuring every screen in the live app rather
   than looking at one: .rv-exit-left is absolute at top:14px and is
   44px tall, so it ends at 58px - but .rv-body only had 40px of top
   padding. The back button has been sitting ON TOP of the eyebrow
   text by 18px on THIRTEEN screens, since those screens were built.

   Not a regression. A bug that shipped and nobody measured. It is
   exactly the class of thing Chance means by "flat, bland, old
   style" - the app looking not-quite-finished for a reason no one
   could name.

   :has() targets only bodies that actually contain the button, so
   screens without one keep their original spacing.

   MEASURE THE LIVE DOM. 46px was a guess on the lodge screen and
   was still 12px short. 68px is measured.
   ================================================================== */
.rv-body:has(> .rv-exit-left){ padding-top:68px; }

/* ==================================================================
   PRIMARY BUTTONS - ONE TREATMENT, EVERYWHERE
   ------------------------------------------------------------------
   Chance found this, not us. He flipped between screens and noticed
   that some green buttons are glossy and have depth and some are
   "flat, bland, plain and old style" - his words. He was right, and
   it was worse than a near-miss: the polished treatment ALREADY
   EXISTED and had only ever been applied to .welcome-btn. Every
   other screen in the app used .rv-btn-primary, which was a solid
   fill with a 10px radius and no shadow at all. 30 flat button
   rules against 4 with any depth.

   So this is not a new design. It is the design that was already
   here, finally applied to all of it: vertical gradient, a lift
   shadow in the brand colour, an inner top highlight and bottom
   shade for the bevel, and a gloss sheet over the top half.

   ADD NEW PRIMARY BUTTONS TO THIS SELECTOR LIST. That is the whole
   point - the next person to invent their own button is how the app
   ends up looking half-finished again.
   ================================================================== */
.rv-btn-primary,
.welcome-btn,
.win-btn-primary,
.launch-btn.ready,
.ggtl-update-btn,
.cele-btn,
.sig-done,
.sh-sign,
.lr-send,
.lr-confirm,
.cert-file-btn,
.ct-track,
.t-run,
.t-do,
.q-big,
.rv-submit,
.result-proceed,
.enlist-accept,
.badge-proceed,
.briefing-go,
.fl-go,
.fl-note-btn,
.rp-reassure-btn,
.cue-on-btn,
.tour-next{
  position:relative;overflow:hidden;border:none;border-radius:14px;
  background:linear-gradient(180deg,#c9f45c 0%,var(--acid) 52%,#82bd27 100%);
  color:#0a1a0e;
  box-shadow:
    0 10px 26px rgba(163,230,53,.26),
    inset 0 1px 0 rgba(255,255,255,.6),
    inset 0 -1px 0 rgba(0,0,0,.2);
  transition:transform .12s ease, box-shadow .12s ease, filter .12s ease;
}
/* The gloss. Sits over the top half only - that is what reads as glass
   rather than as a plain gradient. pointer-events:none so it never eats
   a tap. */
.rv-btn-primary::after,
.welcome-btn::after,
.win-btn-primary::after,
.launch-btn.ready::after,
.ggtl-update-btn::after,
.cele-btn::after,
.sig-done::after,
.sh-sign::after,
.lr-send::after,
.lr-confirm::after,
.cert-file-btn::after,
.ct-track::after,
.t-run::after,
.t-do::after,
.q-big::after,
.rv-submit::after,
.result-proceed::after,
.enlist-accept::after,
.badge-proceed::after,
.briefing-go::after,
.fl-go::after,
.fl-note-btn::after,
.rp-reassure-btn::after,
.cue-on-btn::after,
.tour-next::after{
  content:'';position:absolute;left:0;right:0;top:0;height:46%;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0));
}
.rv-btn-primary:active,
.welcome-btn:active,
.win-btn-primary:active,
.launch-btn.ready:active,
.ggtl-update-btn:active,
.cele-btn:active,
.sig-done:active,
.sh-sign:active,
.lr-send:active,
.lr-confirm:active,
.cert-file-btn:active,
.ct-track:active,
.t-run:active,
.t-do:active,
.q-big:active,
.rv-submit:active,
.result-proceed:active,
.enlist-accept:active,
.badge-proceed:active,
.briefing-go:active,
.fl-go:active,
.fl-note-btn:active,
.rp-reassure-btn:active,
.cue-on-btn:active,
.tour-next:active{
  transform:translateY(1px) scale(.985);
  box-shadow:
    0 4px 12px rgba(163,230,53,.22),
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 -1px 0 rgba(0,0,0,.22);
}
/* The disabled list had drifted to 6 of the 12 classes above. A button
   missing from here stays glossy and lifted while disabled, which reads
   as tappable. Kept deliberately in step with the base list - if you add
   a class up there, add it here in the same edit. */
.rv-btn-primary:disabled,
.welcome-btn:disabled,
.win-btn-primary:disabled,
.launch-btn.ready:disabled,
.ggtl-update-btn:disabled,
.cele-btn:disabled,
.sig-done:disabled,
.sh-sign:disabled,
.lr-send:disabled,
.lr-confirm:disabled,
.cert-file-btn:disabled,
.ct-track:disabled,
.t-run:disabled,
.t-do:disabled,
.q-big:disabled,
.rv-submit:disabled,
.result-proceed:disabled,
.enlist-accept:disabled,
.badge-proceed:disabled,
.briefing-go:disabled,
.fl-go:disabled,
.fl-note-btn:disabled,
.rp-reassure-btn:disabled,
.cue-on-btn:disabled,
.tour-next:disabled{
  opacity:.35;pointer-events:none;box-shadow:none;
}

/* SECONDARY BUTTONS - outlined, not filled. Same family, quieter.
   These carried no depth at all either. */
.rv-btn-link,
.win-btn-secondary,
.sig-clear,
.sh-exit,
.lr-tab,
.lr-opt,
.an-secondary{
  border-radius:12px;
  background:rgba(163,230,53,.05);
  -webkit-backdrop-filter:blur(10px) saturate(140%);
  backdrop-filter:blur(10px) saturate(140%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
  transition:transform .12s ease, background .12s ease;
}
.rv-btn-link:active,
.win-btn-secondary:active,
.sig-clear:active,
.sh-exit:active,
.lr-tab:active,
.lr-opt:active,
.an-secondary:active{ transform:translateY(1px) scale(.99); }

/* Selected states keep the brand colour but gain the same bevel so a
   chosen option reads as pressed-in rather than just tinted. */
.lr-opt-on,.lr-tab-on,.rv-opt.selected,.iq-opt.selected,.h-chip.selected{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 0 rgba(0,0,0,.18);
}

@media (prefers-reduced-motion:reduce){
  .rv-btn-primary,.welcome-btn,.win-btn-primary,.cele-btn,.sig-done,
  .sh-sign,.lr-send,.lr-confirm,.cert-file-btn,.ct-track,
  .launch-btn.ready,.ggtl-update-btn,.t-run,.t-do,.q-big,.rv-submit,
  .result-proceed,.enlist-accept,.badge-proceed,.briefing-go,
  .fl-go,.fl-note-btn,.rp-reassure-btn,.cue-on-btn,.tour-next{transition:none}
}

.ct-track{width:100%;min-height:48px;margin:4px 0 18px;letter-spacing:1px}

#shipBody{padding:18px 16px 34px}

.sh-head{display:flex;justify-content:space-between;align-items:baseline;
  border-bottom:1px solid var(--border);padding-bottom:10px}
.sh-brand{font-family:var(--font-display);font-size:15px;letter-spacing:2px;color:var(--acid)}
.sh-org{font-family:var(--font-mono);font-size:11px;color:var(--ink-muted)}

.sh-track{display:flex;justify-content:space-between;align-items:center;margin:14px 0 4px}
.sh-track-l{font-family:var(--font-mono);font-size:11px;letter-spacing:1.4px;color:var(--ink-muted)}
.sh-pill{font-family:var(--font-mono);font-size:11px;letter-spacing:1px;
  padding:4px 11px;border-radius:20px;border:1px solid}
.sh-pill-wait{color:var(--ink-muted);border-color:var(--border-bright)}
.sh-pill-move{color:var(--cold);border-color:var(--cold)}
.sh-pill-done{color:var(--acid);border-color:var(--acid)}

.sh-num{font-family:var(--font-mono);font-size:17px;letter-spacing:1.6px;color:var(--ink);margin-bottom:14px}

.sh-manifest{background:rgba(163,230,53,.05);border:1px solid var(--border);
  border-radius:10px;padding:11px 12px;margin-bottom:18px}
.sh-m{display:flex;justify-content:space-between;gap:12px;font-family:var(--font-mono);
  font-size:11px;padding:3px 0;color:var(--ink-muted)}
.sh-m span:last-child{color:var(--ink-soft);text-align:right}

.sh-sec{font-family:var(--font-mono);font-size:11px;letter-spacing:1.4px;
  color:var(--ink-muted);margin:0 0 4px}

.sh-row{display:flex;gap:12px}
.sh-rail{flex:0 0 10px;display:flex;flex-direction:column;align-items:center}
.sh-dot{width:10px;height:10px;border-radius:50%;margin-top:13px;background:var(--border-bright)}
.sh-line{flex:1;width:1px;background:var(--border);margin-top:4px}
.sh-row.sh-last .sh-line{display:none}
.sh-cell{flex:1;min-width:0;padding:10px 0 10px}

.sh-t{font-family:var(--font-mono);font-size:12px;letter-spacing:.7px;color:var(--ink-muted)}
.sh-s{font-size:12px;color:var(--ink-muted);margin-top:3px;line-height:1.45}
.sh-ts{font-family:var(--font-mono);font-size:11px;color:var(--ink-muted);margin-top:4px;opacity:.8}

.sh-done .sh-dot{background:var(--acid)}
.sh-done .sh-t{color:var(--ink-soft)}
.sh-now .sh-dot{background:var(--cold);box-shadow:0 0 0 4px rgba(56,189,248,.16)}
.sh-now .sh-t{color:var(--ink)}
.sh-now .sh-s{color:var(--ink-soft)}

.sh-gate{margin-top:10px}
.sh-bar{height:6px;background:rgba(163,230,53,.12);border-radius:4px;overflow:hidden}
.sh-fill{height:100%;background:var(--acid);border-radius:4px;transition:width .4s ease}
.sh-gate-n{font-family:var(--font-mono);font-size:12px;color:var(--acid);margin-top:7px}
.sh-gate-s{font-size:12px;color:var(--ink-muted);margin-top:5px;line-height:1.5}
.sh-crew{font-size:12px;color:var(--cold);margin-top:6px;line-height:1.5}

/* THE MACHINE IS ALREADY BOUGHT.
   He was worried the price would rise when the sale ended. This answers that
   where he goes to worry about it. Source for the claim: Nick, 2026-08-05. */
.sh-secured{border:1px solid var(--border-bright);border-radius:10px;
  padding:13px 14px;margin:0 0 20px;background:rgba(163,230,53,.05)}
.sh-secured-t{font-family:var(--font-mono);font-size:11px;letter-spacing:1.3px;
  color:var(--acid);margin-bottom:8px}
.sh-secured-b{font-size:13px;color:var(--ink-soft);line-height:1.6}

.sh-sign{margin-top:12px;width:100%;min-height:48px}

/* THE CELEBRATION. Full takeover so it cannot be missed or scrolled past.
   Pending, not momentary - if he crosses 30 with the phone in his pocket
   this is waiting for him when he looks. */
/* LANDSCAPE / SHORT VIEWPORTS. ship.js carries its own copy of these rules
   and that copy wins; this is kept in step so the two can never disagree.
   align-items:flex-start + margin:auto on the card centres when there is
   room and SCROLLS when there is not. align-items:center with overflow
   clips the top unreachably - on a phone held sideways that put the only
   button on the DELIVERED screen off the bottom of the display. */
.cele{position:fixed;inset:0;z-index:9998;background:rgba(4,16,10,.97);
  display:flex;align-items:flex-start;justify-content:center;padding:22px;
  overflow-y:auto;-webkit-overflow-scrolling:touch;
  animation:celeIn .45s ease}
@keyframes celeIn{from{opacity:0}to{opacity:1}}
.cele-card{max-width:420px;width:100%;border:1px solid var(--acid);
  border-radius:14px;padding:26px 22px;background:rgba(163,230,53,.06);
  text-align:center;margin:auto}

/* Short viewport = phone on its side, or a small desktop window. Keyed on
   HEIGHT rather than orientation, because a short window is the same problem.
   Type shrinks; tap targets never go below 44px. */
@media (max-height:520px){
  .cele-card{padding:16px 18px}
  .cele-title{font-size:32px;letter-spacing:2px;margin:6px 0 10px}
  .cele-body{font-size:12.5px;line-height:1.5}
  .cele-body p{margin:0 0 8px}
  .cele-btn{min-height:46px;margin-top:4px}
  .sh-hero-v{font-size:34px}
  #shipBody{padding:14px 16px 26px}
}
.cele-eyebrow{font-family:var(--font-mono);font-size:10px;letter-spacing:1.8px;
  color:var(--ink-muted)}
.cele-title{font-family:var(--font-display);font-size:56px;line-height:1;
  letter-spacing:4px;color:var(--acid);margin:12px 0 16px}
.cele-body{font-size:14px;line-height:1.65;color:var(--ink-soft);text-align:left}
.cele-body p{margin:0 0 11px}
.cele-body strong{color:var(--ink)}
.cele-btn{width:100%;min-height:50px;margin-top:8px;letter-spacing:1.2px}
@media (prefers-reduced-motion:reduce){.cele{animation:none}}

.sh-exit{margin-top:24px;width:100%;min-height:44px;background:transparent;
  border:1px solid var(--border-bright);border-radius:10px;color:var(--ink-soft);
  font-family:var(--font-mono);font-size:13px;letter-spacing:1px;cursor:pointer}
.sh-exit:active{background:rgba(163,230,53,.06)}

@media (prefers-reduced-motion:reduce){
  .sh-fill{transition:none}
  .sh-now .sh-dot{box-shadow:none;outline:2px solid rgba(56,189,248,.4)}
}

/* ==================================================================
   THE GUIDE — tour.js
   ------------------------------------------------------------------
   Built 2026-08-20. Nick opened the app and couldn't tell what screen
   he'd landed on. If he can't orient, a nine-year-old can't either.

   The spotlight is ONE element. .tour-ring is positioned over the
   target and carries a 9999px spread shadow, so everything outside
   the ring is dimmed by the ring itself. No masks, no clip-path, no
   four-panel geometry to get wrong on a rotate. It's the most robust
   version of this effect and it degrades to nothing if the ring is
   never inserted.

   Buttons here reuse .rv-btn-primary rather than inventing a look.
   A guide that doesn't match the app is telling you the app has no
   design system.
   ================================================================== */

body.tour-open{ overflow:hidden; }

#tourLayer{ position:fixed; inset:0; z-index:9997; }

/* Centred variant — the degraded path when a step's element is gone.
   It dims on its own since there's no ring to do it. */
#tourLayer.tour-centred{
  background:rgba(4,16,10,.93);
  display:flex; align-items:flex-start; justify-content:center;
  padding:22px; overflow-y:auto; -webkit-overflow-scrolling:touch;
}
#tourLayer.tour-centred .tour-card{ position:relative; margin:auto; }

.tour-ring{
  position:fixed; border-radius:14px; pointer-events:none;
  border:2px solid var(--acid);
  box-shadow:0 0 0 9999px rgba(4,16,10,.86), 0 0 22px rgba(163,230,53,.45);
  transition:top .25s ease,left .25s ease,width .25s ease,height .25s ease;
}

.tour-card{
  position:fixed; width:min(340px, calc(100vw - 20px));
  /* A card taller than the viewport pins at top:10 and runs off the
     bottom, taking GOT IT and Close with it. Escape saves a desktop;
     a phone has no Escape. */
  max-height:calc(100vh - 20px); overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  background:rgba(10,30,14,.97);
  border:1px solid var(--border-bright); border-radius:14px;
  padding:16px 16px 14px;
  box-shadow:0 12px 40px rgba(0,0,0,.6);
  -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(140%);
  backdrop-filter:blur(var(--glass-blur)) saturate(140%);
  animation:tourIn .22s ease;
}
@keyframes tourIn{ from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:none} }

.tour-eyebrow{
  font-family:var(--font-mono); font-size:10px; letter-spacing:1.6px;
  color:var(--ink-muted); margin-bottom:6px;
}
.tour-title{
  font-family:var(--font-display); font-size:19px; font-weight:700;
  letter-spacing:1.2px; color:var(--acid); line-height:1.15; margin-bottom:8px;
}
.tour-body{
  font-family:var(--font-body); font-size:14px; line-height:1.6;
  color:var(--ink-soft);
}

/* Dots, never "3 of 7". Guardrail G2 — no denominators he can read.
   They're tappable so a step can be revisited without going back one
   at a time. 44px hit area via padding, 8px visible dot. */
.tour-dots{
  display:flex; gap:0; justify-content:center; margin:8px 0 2px;
  flex-wrap:wrap;
}
/* 8px visible dot, 44x44 hit area via transparent border. The border was
   18px top/bottom but only 7px left/right, giving 44x22 - a 24px tap pitch
   that would put a mis-tap on the neighbouring dot and jump him to the
   wrong step. Both axes are 18px now. Five dots at 44px plus gaps still
   fits the card. */
.tour-dot{
  width:8px; height:8px; padding:0; border:none; border-radius:50%;
  background:rgba(163,230,53,.22); cursor:pointer;
  box-sizing:content-box;
  border-top:18px solid transparent; border-bottom:18px solid transparent;
  border-left:18px solid transparent; border-right:18px solid transparent;
  background-clip:content-box;
}
.tour-dot-on{ background:var(--acid); background-clip:content-box; }

.tour-actions{ display:flex; gap:8px; align-items:stretch; margin-top:4px; }
.tour-next{
  flex:1; min-height:46px; font-family:var(--font-mono); font-size:13px;
  letter-spacing:1.2px; font-weight:600; cursor:pointer;
}
.tour-back{
  flex:0 0 auto; min-height:46px; padding:0 16px;
  background:rgba(163,230,53,.05); border:1px solid var(--border-bright);
  border-radius:12px; color:var(--ink-soft);
  font-family:var(--font-mono); font-size:12px; letter-spacing:1px; cursor:pointer;
}
.tour-back:active{ transform:translateY(1px) scale(.99); }

.tour-skip{
  display:block; width:100%; min-height:44px; margin-top:6px;
  background:transparent; border:none; color:var(--ink-muted);
  font-family:var(--font-mono); font-size:12px; letter-spacing:1px; cursor:pointer;
}
.tour-skip:active{ color:var(--ink-soft); }

/* The ? button. Sits directly above the LOG fab (right:16px, bottom:78px,
   z-index:130) — same rail, deliberately quieter, and 44px so it clears
   the touch floor that .rv-exit and .rt-exit both had to be fixed for. */
/* .q-fab is 62px tall at bottom:78px, so it occupies 78-140. At bottom:146
   the gap was 6px, and the short-viewport value of 130 actually OVERLAPPED
   it by 10px - and since .q-fab is z-index 130 against this 129, LOG would
   have silently eaten those taps. 150 on both. */
.tour-fab{
  position:fixed; right:16px; bottom:150px; z-index:129;
  width:44px; height:44px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgba(10,30,14,.9); border:1px solid var(--border-bright);
  color:var(--ink-soft); font-family:var(--font-display);
  font-size:21px; font-weight:700; cursor:pointer;
  -webkit-backdrop-filter:blur(10px) saturate(140%);
  backdrop-filter:blur(10px) saturate(140%);
  box-shadow:0 4px 14px rgba(0,0,0,.4);
}
.tour-fab:active{ transform:scale(.94); background:rgba(163,230,53,.12); }

/* Short viewport / landscape. Same rule the .cele overlay already
   proved: flex-start + margin auto scrolls instead of clipping the
   top unreachably. An anchored card just gets smaller. */
@media (max-height:520px){
  .tour-card{ padding:12px 14px 10px; width:min(320px, calc(100vw - 20px)); }
  .tour-title{ font-size:17px; margin-bottom:6px; }
  .tour-body{ font-size:13px; line-height:1.5; }
  .tour-dots{ margin:10px 0 2px; }
  .tour-next,.tour-back{ min-height:44px; }
  .tour-skip{ min-height:40px; margin-top:2px; }
  .tour-fab{ bottom:150px; }
}

@media (prefers-reduced-motion:reduce){
  .tour-card{ animation:none; }
  .tour-ring{ transition:none; }
}

/* ==================================================================
   REDUCED MOTION — the press transform, not just the transition
   ------------------------------------------------------------------
   Caught in review. styles-b.css already killed :active transforms for
   reduced-motion users on .q-big, .t-do, .t-run and .fl-go - but those
   rules are 0,2,0 specificity and so is the new :active list above,
   which loads later. A media query adds no specificity, so the press
   transform came straight back for exactly the users who asked for it
   not to. Killing it here, after the rule that reinstated it.
   ================================================================== */
@media (prefers-reduced-motion:reduce){
  .rv-btn-primary:active,.welcome-btn:active,.win-btn-primary:active,
  .launch-btn.ready:active,.ggtl-update-btn:active,.cele-btn:active,
  .sig-done:active,.sh-sign:active,.lr-send:active,.lr-confirm:active,
  .cert-file-btn:active,.ct-track:active,.t-run:active,.t-do:active,
  .q-big:active,.rv-submit:active,.result-proceed:active,
  .enlist-accept:active,.badge-proceed:active,.briefing-go:active,
  .fl-go:active,.fl-note-btn:active,.rp-reassure-btn:active,
  .cue-on-btn:active,.tour-next:active{ transform:none }
  /* .t-run:active must be named too. The :active rule above is 0,2,0 and
     sets an explicit box-shadow, so a bare .t-run at 0,1,0 loses to it and
     the green lift flashes back on press - for the users who asked for no
     motion. */
  .t-run,.t-run:active{ box-shadow:none }
}

/* ==================================================================
   BACK BUTTON CLEARANCE — the two screens :has() cannot reach
   ------------------------------------------------------------------
   The rule at the top of this file handles .rv-body children. These
   two put .rv-exit-left directly under .screen instead, so the
   selector misses them and the button paints on top of the title.
   .rv-exit is absolute at top:14px and 44px tall, ending at 58px.
   Pre-existing on both; fixed here because the labnotes screen was
   already being touched this release.

   Padding the header was the first fix and it was wrong: both headers
   are inside a position:sticky wrapper, so the padding pins a 58px
   dead band to the top of the viewport for the whole screen once you
   scroll. Taking the button out of absolute positioning instead costs
   nothing and leaves no gap - it just sits above the title in normal
   flow, which is where it looked like it was meant to be anyway.
   ================================================================== */
#screen-customize > .rv-exit-left,
#screen-labnotes > .rv-exit-left{
  position:static; margin:14px 0 2px 14px; display:inline-flex;
  align-items:center;
}
