/* Vanderbilt Networking — "Game-Day Program" varsity print theme.
   A 1920s athletics-program aesthetic pushed through a modern neubrutalist
   lens: cream paper with real print grain, hard ink-line frames with offset
   block shadows, Clash Display caps, Sentient italic masthead, gold
   marker highlights, stamp-style badges, scoreboard tiles, and a duotone
   photo of Kirkland Hall. Spring-physics entrances (overshoot cubic-bezier
   + the stagger script in index.html) make every view cascade in.

   The Commodore scene stays: sun, clouds, pennants, campus skyline, gulls,
   and the ship with Mr. C sailing the bottom of every page.

   Two constraints this file must respect:
   1. Every class name the app renders is styled here — nothing was renamed.
   2. the app modules set inline styles using --red (as text), --gold-pale (as a card
      background, with inherited text), --gold and --gold-dark. All four are
      tuned for the light paper background. */

:root {
  color-scheme: light;

  /* --- paper (old "space" names kept — aliases below use them) --- */
  --space-900: #f5efdd;
  --space-800: #eee5cc;
  --space-700: #e6d9b8;
  --space-600: #dbcb9f;

  /* --- bronze family (old nebula names kept for the gradients below) --- */
  --violet:  #8a6d2f;
  --indigo:  #a8873a;
  --cyan:    #b8912f;
  --magenta: #6b5426;

  /* --- Vanderbilt gold + ink --- */
  --ink-black:   #211a10;   /* the printing ink everything is drawn with */
  --gold:        #b8912f;   /* primary accent — dark enough to read on paper */
  --gold-bright: #cfae70;   /* Vanderbilt web gold, for fills under ink text */
  --gold-dark:   #8a6d2f;   /* checkbox accent-color — visible on light */
  --gold-pale:   #f3e6c4;   /* card background; inherited ink text reads fine */
  --gold-glow:   rgba(184, 145, 47, .25);
  /* Secondary accents: deep gold for headings, pale gold for highlights. */
  --mint:        #8a6d2f;
  --mint-deep:   #6b5426;
  --ice:         #e9dcb4;
  --trust:       #24549e;
  --green:       #17714a;
  --green-pale:  rgba(23, 113, 74, .13);
  --red:         #bb3350;   /* used as inline text colour — reads on paper */
  --red-pale:    rgba(187, 51, 80, .1);

  /* --- surfaces & text --- */
  --bg:      var(--space-900);
  --surface: #fffcf2;
  --raised:  #f4ecd6;
  --line:    rgba(33, 26, 16, .25);
  --line-strong: rgba(33, 26, 16, .55);
  --ink:     #211a10;
  --gray:    #6f6450;
  --gray-light: #9c9078;

  /* legacy aliases — kept so nothing dangles */
  --navy: var(--ink-black);
  --black: var(--ink-black);
  --light: var(--bg);
  --white: var(--surface);
  --navy-700: #33291b;

  /* Hard print shadows — blocks of ink, not blur. */
  --shadow-sm: 2px 2px 0 rgba(33, 26, 16, .9);
  --shadow:    4px 4px 0 rgba(33, 26, 16, .9);
  --shadow-lg: 8px 8px 0 rgba(33, 26, 16, .9);
  --radius: 3px;

  --sans: "Satoshi", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --serif: "Sentient", Georgia, "Times New Roman", serif;
  --mono: "JetBrains Mono", Consolas, "Courier New", monospace;
  --display: "Clash Display", "Arial Narrow", var(--sans);

  --ease: cubic-bezier(.22, .61, .36, 1);
  /* The spring: overshoots, then settles. Framer-Motion energy, zero JS. */
  --spring: cubic-bezier(.34, 1.56, .64, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--bg);
  display: flex;
  min-height: 100vh;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* --- daylight wash + the paper itself --- */
body::before {
  content: "";
  position: fixed; inset: 0;
  z-index: -3; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(163, 195, 219, .35) 0%, rgba(203, 222, 234, .18) 15%, transparent 40%),
    radial-gradient(42% 34% at 12% 2%, rgba(244, 208, 120, .35), transparent 70%);
}
/* Print grain over everything — the page feels pulled off a press. */
body::after {
  content: "";
  position: fixed; inset: 0;
  z-index: 120; pointer-events: none;
  opacity: .033;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.6'/%3E%3C/svg%3E");
}

/* --- the Commodore scene --------------------------------------------------
   Sun and clouds up top with the pennant string, a ship's-wheel watermark,
   and an ocean along the bottom with the campus skyline on the horizon and
   the ship sailing across. Purely SVG + CSS: no canvas, no JS. */
#sky {
  position: fixed; inset: 0;
  z-index: -2; pointer-events: none; overflow: hidden;
}

/* Clouds, crossing at their own pace. */
.cloud { position: absolute; opacity: .9; }
.cloud svg { display: block; width: 100%; height: auto; }
.cloud-1 { top: 7%;  width: 170px; animation: cloud-drift 95s  linear infinite; }
.cloud-2 { top: 15%; width: 120px; opacity: .7; animation: cloud-drift 135s linear infinite -40s; }
.cloud-3 { top: 3%;  width: 90px;  opacity: .55; animation: cloud-drift 170s linear infinite -110s; }
@keyframes cloud-drift {
  from { transform: translateX(calc(100vw + 180px)); }
  to   { transform: translateX(-220px); }
}

/* Game-day pennants, swaying from the top edge. */
.pennants {
  position: absolute; top: 0; left: -2%; width: 104%; height: 64px;
  opacity: .95;
  transform-origin: 50% 0;
  animation: pennant-sway 6.5s ease-in-out infinite alternate;
}
@keyframes pennant-sway {
  from { transform: rotate(-.9deg) translateY(-2px); }
  to   { transform: rotate(.9deg)  translateY(0); }
}

/* Music City: notes drift across on long staggered loops, swaying like
   they're carried on a song from Broadway. */
.note { position: absolute; width: 24px; opacity: 0; }
.note svg { display: block; animation: note-sway 2.6s ease-in-out infinite alternate; }
.note-1 { top: 17%; animation: note-drift 36s linear infinite 2s; }
.note-2 { top: 25%; width: 30px; animation: note-drift 50s linear infinite 15s; }
.note-3 { top: 10%; width: 18px; animation: note-drift 64s linear infinite 30s; }
@keyframes note-drift {
  0%   { transform: translate(-40px, 0); opacity: 0; }
  4%   { opacity: .55; }
  30%  { transform: translate(30vw, -18px); }
  60%  { transform: translate(62vw, 6px); }
  96%  { opacity: .55; }
  100% { transform: translate(calc(100vw + 40px), -12px); opacity: 0; }
}
@keyframes note-sway { from { transform: rotate(-9deg); } to { transform: rotate(9deg); } }

/* ANCHOR DOWN, drawn as well as shouted. Hangs bottom-left, the counterweight
   to the guitar, swinging slowly on its rode. */
.anchor {
  /* Clear of the sidebar, which is opaque and 236px wide — at left:16px the
     whole anchor sat behind it and was never seen. */
  position: absolute; left: 268px; bottom: 176px;
  width: 138px; height: 230px;
  color: rgba(138, 109, 47, .2);
  transform-origin: 50% 4%;
  animation: anchor-swing 11s ease-in-out infinite alternate;
}
@keyframes anchor-swing {
  from { transform: rotate(-5deg); }
  to   { transform: rotate(5deg); }
}

/* A ship's wheel turning behind the content — one slow revolution, faint
   enough to read as watermark rather than ornament. */
.wheel {
  position: absolute; left: 44%; top: 22%;
  width: 320px; height: 320px;
  color: rgba(138, 109, 47, .075);
  animation: wheel-turn 120s linear infinite;
}
@keyframes wheel-turn { to { transform: rotate(360deg); } }

/* Music City watermark: an acoustic guitar leaning behind the content,
   swaying almost imperceptibly. */
.guitar {
  position: absolute; right: 10px; bottom: -120px;
  width: 250px; height: 525px;
  color: rgba(138, 109, 47, .12);
  transform: rotate(-18deg);
  transform-origin: 50% 10%;
  animation: guitar-sway 14s ease-in-out infinite alternate;
}
@keyframes guitar-sway {
  from { transform: rotate(-20deg); }
  to   { transform: rotate(-15deg); }
}

/* The honky-tonk marquee: hangs over the postcard corner, swinging on its
   chains while the bulbs take turns. A daytime marquee — bulbs, no glow. */
.marquee {
  position: absolute; top: 54px; right: 36px;
  width: 190px;
  transform-origin: 50% 0;
  animation: marquee-swing 5.5s ease-in-out infinite alternate;
}
.marquee svg { display: block; width: 100%; height: auto; }
@keyframes marquee-swing {
  from { transform: rotate(-2deg); }
  to   { transform: rotate(2deg); }
}
.bulbs circle { animation: bulb-blink 1.6s steps(1) infinite; }
.bulbs circle:nth-child(even) { animation-delay: -.8s; }
@keyframes bulb-blink {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: .3; }
}

/* The river: Nashville on the far bank, two drifting wave layers, the
   riverboat sailing between them. */
.ocean { position: absolute; left: 0; right: 0; bottom: 0; height: 190px; }
.skyline {
  position: absolute; bottom: 56px; left: 0; width: 100%; height: 124px;
  color: #a9905e;
}
.wave {
  position: absolute; bottom: 0; left: 0;
  width: 200%; height: 100%;
}
.wave-back  { height: 96px;  animation: wave-drift 24s linear infinite; }
.wave-front { height: 58px;  animation: wave-drift 13s linear infinite; }
@keyframes wave-drift { to { transform: translateX(-50%); } }

/* The ship crosses the whole viewport, unhurried, then comes around again. */
.ship-track {
  position: absolute; bottom: 30px; left: 0;
  animation: ship-sail 160s linear infinite;
  will-change: transform;
}
/* -100% is the element's OWN width, so she starts fully off-stage without a
   hard-coded pixel offset to keep in sync. */
@keyframes ship-sail {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100vw); }
}

/* --- the banner plane ------------------------------------------------------
   The ship crosses once every 160s, which is far too rare to rely on for
   something a student actually needs to read. The plane runs the same errand
   on a 24s lap, so one is almost always in the air. */
/* Hidden by default: inside the CRM it is a distraction crossing the work.
   It flies on the way in -- the sign-in screen -- and on the front page, which
   keeps its own copy. */
.plane-track { display: none; }
body.auth-view .plane-track {
  display: block;
  position: absolute; top: 26%; left: 0;
  animation: plane-fly 24s linear infinite;
  will-change: transform;
}
@keyframes plane-fly {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100vw); }
}
/* Nose leads, banner trails: the rig reads [banner][plane] and flies right, so
   the plane clears the left edge first and drags the message across after it. */
.plane-rig { display: flex; align-items: center; animation: plane-bob 6s ease-in-out infinite; }
@keyframes plane-bob {
  0%, 100% { transform: translateY(0)    rotate(-.8deg); }
  50%      { transform: translateY(-9px) rotate(.8deg); }
}
.plane { display: block; width: 104px; height: auto; flex: none; }
.plane-banner {
  margin: 0 -2px 0 0; padding: 7px 16px 7px 26px;
  white-space: nowrap;
  font-size: 13px; font-weight: 700; letter-spacing: .01em;
  color: #2b2213;
  background: linear-gradient(180deg, #f6ecca, #e2d09b);
  border: 1.5px solid rgba(138, 109, 47, .55); border-right: none;
  box-shadow: 0 2px 5px rgba(33, 26, 16, .12);
  /* swallowtail bitten out of the trailing edge */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 12px 50%);
}
.ship-bob { animation: ship-bob 5.5s ease-in-out infinite; }
@keyframes ship-bob {
  0%, 100% { transform: translateY(0) rotate(-1.6deg); }
  50%      { transform: translateY(-7px) rotate(1.6deg); }
}
.ship { display: block; width: 232px; height: auto; }

/* Canvas breathes; the colors snap at the masthead. */
.sails {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: sail-billow 6.5s ease-in-out infinite;
}
@keyframes sail-billow {
  0%, 100% { transform: scaleX(1); }
  50%      { transform: scaleX(1.045); }
}
.flag {
  transform-box: fill-box; transform-origin: 0% 50%;
  animation: flag-snap 1.7s ease-in-out infinite;
}
@keyframes flag-snap {
  0%, 100% { transform: scaleY(1) skewY(0); }
  30%      { transform: scaleY(.82) skewY(4deg); }
  65%      { transform: scaleY(1.06) skewY(-3deg); }
}

/* Mr. C's real head bobbles like a dashboard figure. */
.mrc-head {
  transform-box: fill-box; transform-origin: 50% 92%;
  animation: head-bob 3.2s ease-in-out infinite;
}
@keyframes head-bob {
  0%, 100% { transform: rotate(-5deg); }
  50%      { transform: rotate(5deg); }
}

/* Every so often he lifts the bicorne to the room and puts it back. */
.mrc-hat {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: hat-tip 13s ease-in-out infinite;
}
@keyframes hat-tip {
  0%, 78%, 100% { transform: translateY(0) rotate(0deg); }
  84%           { transform: translateY(-3.5px) rotate(-13deg); }
  92%           { transform: translateY(-2px) rotate(-6deg); }
}

/* Mr. Commodore waves from the deck. */
.m-arm {
  transform-box: fill-box; transform-origin: 15% 95%;
  animation: m-wave 2.6s ease-in-out infinite;
}
@keyframes m-wave {
  0%, 20%, 100% { transform: rotate(0deg); }
  40%           { transform: rotate(26deg); }
  60%           { transform: rotate(-4deg); }
  80%           { transform: rotate(20deg); }
}

::selection { background: var(--gold-bright); color: #241a08; }

/* A band of gold sweeps across a nav item on hover — the sidebar is the one
   surface a student's cursor lives on. */
.nav-btn { position: relative; overflow: hidden; }
.nav-btn::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(207, 174, 112, .32) 50%, transparent 80%);
  transform: translateX(-120%);
  pointer-events: none;
}
.nav-btn:hover::after { animation: nav-sweep .65s var(--ease); }
@keyframes nav-sweep { to { transform: translateX(120%); } }

/* ---------- sidebar: the varsity banner ---------- */
.sidebar {
  width: 236px;
  background: linear-gradient(180deg, #171310, #221c14);
  color: #e6dfd0;
  display: flex; flex-direction: column;
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 10;
  border-right: 3px solid var(--ink-black);
  box-shadow: inset -4px 0 0 var(--gold-bright);
  /* Fixed to both edges, so anything taller than the screen used to be simply
     unreachable — that is how Sign out went missing on short laptops. Scroll
     rather than clip, and never let a child shrink itself to fit. */
  overflow-y: auto;
  overscroll-behavior: contain;
}
.sidebar > * { flex-shrink: 0; }
.brand { padding: 26px 20px 20px; border-bottom: 2px solid rgba(207, 174, 112, .35); }
.brand-title {
  font-family: var(--serif);
  font-style: italic;
  font-size: 21px; font-weight: 700; line-height: 1.15; color: #fff;
}
.brand-title::after {
  content: ""; display: block; height: 4px; width: 44px; margin-top: 12px;
  background: repeating-linear-gradient(90deg, #cfae70 0 8px, transparent 8px 12px);
  animation: rule-sweep 6s var(--ease) infinite;
}
@keyframes rule-sweep {
  0%, 100% { width: 44px; opacity: 1; }
  50%      { width: 84px; opacity: .85; }
}
.brand-sub {
  margin-top: 12px; font-size: 11px;
  color: #a3967e; line-height: 1.7;
}

nav { flex: 1; padding: 18px 0; }
.nav-btn {
  position: relative; display: block; width: calc(100% - 24px); text-align: left;
  margin: 4px 12px; border-radius: var(--radius);
  background: none; border: 1.5px solid transparent; color: #b8ac93;
  padding: 9px 14px; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 600; letter-spacing: .3px;
  transition: color .15s var(--ease), background .15s var(--ease),
              transform .2s var(--spring), border-color .15s var(--ease),
              box-shadow .15s var(--ease);
}
.nav-btn::before {
  content: "★"; position: absolute; right: 12px; top: 50%;
  transform: translateY(-50%) scale(0); color: #211a10; font-size: 10px;
  transition: transform .25s var(--spring);
}
.nav-btn:hover { color: #fff; border-color: rgba(207, 174, 112, .5); transform: translateX(3px); }
.nav-btn.active {
  background: var(--gold-bright); color: #211a10; font-weight: 400;
  border-color: var(--ink-black);
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .55);
}
.nav-btn.active::before { transform: translateY(-50%) scale(1); }
.sidebar-footer { padding: 14px 20px 18px; margin-top: 10px; border-top: 2px solid rgba(207, 174, 112, .35); }
/* Quiet support line at the bottom of the menu. Same muted tone as the brand
   strapline, which is the one grey that reads on the black panel. */
.sidebar-help { margin-top: 12px; font-size: 11px; line-height: 1.6; color: #a3967e; overflow-wrap: anywhere; }
.sidebar-help a { color: var(--gold-bright); text-decoration-color: rgba(207, 174, 112, .45); }
/* The same offer at the foot of the dashboard, set apart from the last card. */
.dash-help { margin: 22px 0 0; font-size: 12px; }

/* ---------- main ---------- */
main {
  flex: 1; margin-left: 236px; padding: 38px 44px 110px; max-width: 1240px;
  animation: view-in .4s var(--spring) both;
}
@keyframes view-in {
  from { opacity: 0; transform: translateY(10px) scale(.995); }
  to   { opacity: 1; transform: none; }
}

/* The masthead: huge italic serif with a gold marker swipe behind it. */
h1 {
  display: inline-block;
  font-family: var(--serif); font-style: italic;
  font-size: 40px; font-weight: 700; color: #1c150b; letter-spacing: -.5px;
  line-height: 1.1;
  background: linear-gradient(transparent 62%, rgba(207, 174, 112, .55) 62%, rgba(207, 174, 112, .55) 94%, transparent 94%);
  padding: 0 6px; margin-left: -6px;
}
h1::after {
  content: ""; display: block; height: 3px; margin-top: 10px;
  background: repeating-linear-gradient(90deg, var(--ink-black) 0 26px, transparent 26px 34px, var(--gold) 34px 40px, transparent 40px 48px);
  animation: rule-in .7s var(--spring) both;
}
@keyframes rule-in { from { transform: scaleX(0); transform-origin: left; } }

.page-sub { color: #5f5442; font-size: 13.5px; margin: 12px 0 26px; max-width: 820px; }
/* The ANCHOR DOWN marquee hangs in the top-right corner. It sits behind the
   text, but its gold-on-black artwork leaves anything crossing it unreadable —
   the Contacts subtitle was running straight through it. Keep the header copy
   out of that corner on the widths where the marquee is actually shown (it is
   hidden below 900px, where the full 820px is available again). */
@media (min-width: 901px) {
  .page-sub { max-width: min(820px, calc(100% - 250px)); }
}
h2 {
  font-size: 12.5px; font-weight: 700; margin: 28px 0 12px; color: #33291b;
  text-transform: uppercase; letter-spacing: 1.2px;
}
h2 .accent { color: var(--gold-dark); margin-right: 8px; font-family: var(--mono); font-weight: 600; }

/* Contact-list selection column: tight, and clicks there never open the row. */
.sel-col { width: 30px; text-align: center; }
.sel-col input { accent-color: var(--gold-dark); cursor: pointer; width: 14px; height: 14px; }

/* Card title on the left, its own controls on the right. */
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.card-head h2 { margin-bottom: 0; }

/* The draft as rich text — select and copy straight out of here and the
   LinkedIn hyperlink survives the paste into Outlook. */
.paste-preview {
  margin-top: 12px; padding: 16px 18px; border-radius: var(--radius);
  background: #fffcf2; border: 1.5px solid var(--ink-black);
  box-shadow: var(--shadow-sm);
  font-size: 13.5px; line-height: 1.55; color: #33291b;
  max-height: 460px; overflow-y: auto; user-select: text;
}
.paste-preview p { margin: 0 0 12px; }
.paste-preview p:last-child { margin-bottom: 0; }
.paste-preview a { color: var(--trust); text-decoration: underline; }

/* The email address, always one click from copied. */
.email-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 0; }
.email-line .mono { color: #4a3f2c; user-select: all; }

a { color: var(--trust); text-decoration-color: rgba(36, 84, 158, .35); text-underline-offset: 2px; }
a:hover { color: var(--gold-dark); }

/* ---------- buttons: print blocks you physically press ---------- */
.btn {
  display: inline-block; border: 1.5px solid var(--ink-black);
  background: #fffcf2; color: #211a10;
  padding: 8px 15px; font-size: 13px; cursor: pointer; border-radius: var(--radius);
  text-decoration: none; font-family: inherit; font-weight: 600; letter-spacing: .2px;
  box-shadow: 3px 3px 0 var(--ink-black);
  transition: transform .12s ease, box-shadow .12s ease, background .15s var(--ease);
}
.btn:hover { background: #f6eed8; transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--ink-black); }
.btn:active { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink-black); }
.btn-gold {
  background: var(--gold-bright); color: #211a10;
  box-shadow: 3px 3px 0 var(--ink-black);
}
.btn-gold:hover { background: #d9bc80; }
.btn-ghost {
  background: transparent; border-color: rgba(207, 174, 112, .55); color: #b8ac93;
  box-shadow: none;
}
.btn-ghost:hover { background: rgba(207, 174, 112, .14); color: #fff; transform: none; box-shadow: none; }
main .btn-ghost { border-color: rgba(33, 26, 16, .4); color: var(--gray); box-shadow: none; }
main .btn-ghost:hover { background: rgba(33, 26, 16, .07); color: var(--ink); }
.btn-sm { padding: 5px 11px; font-size: 12px; box-shadow: 2px 2px 0 var(--ink-black); }
.btn-sm:hover { box-shadow: 3px 3px 0 var(--ink-black); }
.btn-sm:active { box-shadow: 0 0 0 var(--ink-black); }
.btn-xs { padding: 2px 8px; font-size: 11px; letter-spacing: .02em; box-shadow: 2px 2px 0 var(--ink-black); }
.btn-xs:active { box-shadow: 0 0 0 var(--ink-black); }
.btn-block { display: block; text-align: center; width: 100%; }
.btn-danger { background: #fffcf2; border-color: var(--red); color: var(--red); box-shadow: 3px 3px 0 var(--red); }
.btn-danger:hover { background: var(--red-pale); box-shadow: 4px 4px 0 var(--red); }
.btn-danger:active { box-shadow: 0 0 0 var(--red); }
.btn[disabled] { opacity: .35; cursor: not-allowed; transform: none; box-shadow: 2px 2px 0 rgba(33, 26, 16, .4); }

/* ---------- metric tiles: the scoreboard ---------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); gap: 16px; margin-bottom: 12px; }
.tile {
  position: relative; overflow: hidden;
  background: #fffcf2;
  border: 1.5px solid var(--ink-black); border-radius: var(--radius);
  padding: 16px 18px 14px;
  box-shadow: 4px 4px 0 var(--ink-black);
  animation: tile-pop .55s var(--spring) both;
  animation-delay: calc(var(--i, 0) * 50ms);
  transition: transform .2s var(--spring), box-shadow .2s ease;
}
.tile:nth-child(odd)  { transform: rotate(-.4deg); }
.tile:nth-child(even) { transform: rotate(.4deg); }
@keyframes tile-pop { from { opacity: 0; transform: translateY(14px) scale(.94); } }
.tile::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
  background: repeating-linear-gradient(90deg, var(--ink-black) 0 10px, var(--gold-bright) 10px 20px);
}
.tile.gold { background: var(--gold-pale); }
.tile.gold::before { background: var(--gold-bright); }
.tile:hover {
  transform: translate(-2px, -2px) rotate(0deg);
  box-shadow: 6px 6px 0 var(--ink-black);
}
.tile.gold:hover { box-shadow: 6px 6px 0 var(--gold-dark); }
.tile .num {
  font-family: var(--sans); font-size: 38px; font-weight: 900; color: #1c150b;
  letter-spacing: -1px; line-height: 1; font-variant-numeric: tabular-nums;
}
.tile.gold .num { color: var(--gold-dark); }
.tile .label {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .8px;
  color: #6f6450; margin-top: 6px;
}

/* ---------- cards & tables: pages of the program ---------- */
.card {
  background: var(--surface); border: 1.5px solid var(--ink-black); border-radius: var(--radius);
  padding: 20px 22px; margin-bottom: 18px;
  box-shadow: 4px 4px 0 rgba(33, 26, 16, .85);
  animation: card-in .5s var(--spring) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}
@keyframes card-in { from { opacity: 0; transform: translateY(12px) scale(.985); } }

table {
  width: 100%; border-collapse: separate; border-spacing: 0;
  background: #fffcf2; font-size: 13px;
  border: 1.5px solid var(--ink-black); border-radius: var(--radius); overflow: hidden;
}
thead th {
  background: var(--ink-black);
  color: #efe6cf; text-align: left; padding: 9px 13px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .9px; font-weight: 600;
  white-space: nowrap;
}
tbody td { padding: 10px 13px; border-top: 1px solid rgba(33, 26, 16, .14); vertical-align: top; }
tbody tr:first-child td { border-top: none; }

/* Firm bands inside the contacts table. These replace a card-and-header per
   firm: the name still separates the groups, but it costs one line instead of
   a whole table head, and every firm's columns line up because there is now
   only one table. */
tr.firm-row td {
  background: var(--gold-pale);
  border-top: 1.5px solid var(--ink-black);
  padding: 7px 13px;
  font-family: var(--display); font-weight: 600;
  font-size: 13px; letter-spacing: 1.4px; text-transform: uppercase;
  color: #33291b;
}
tr.firm-row td .muted { font-family: var(--sans); letter-spacing: 0; font-size: 11.5px; }
/* Rows are not clickable; only the contact rows below them are. */
tr.firm-row { cursor: default; }

/* The name and its track badge belong on one line. With nine columns competing
   for width the Contact column was being squeezed until the badge dropped
   underneath the name, which left rows at two different heights depending on
   whether a contact had one.
   Only where there is room to give: below this the table is already wider than
   the window, and reserving another 129px would just push it further. */
@media (min-width: 1100px) {
  #list tbody td:nth-child(2) { min-width: 210px; }
}
tbody tr {
  transition: background .14s var(--ease), box-shadow .14s var(--ease);
  animation: row-in .4s ease both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
@keyframes row-in { from { opacity: 0; } }
tbody tr:nth-child(even) { background: rgba(207, 174, 112, .07); }
tbody tr:hover {
  background: var(--gold-pale);
  cursor: pointer; box-shadow: inset 4px 0 0 var(--gold);
}
tbody tr.no-hover:hover { background: inherit; cursor: default; box-shadow: none; }
tbody td b { font-weight: 600; color: #1c150b; }

/* ---------- badges: rubber stamps ---------- */
.badge {
  display: inline-block; padding: 2px 8px; border-radius: 2px;
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
  letter-spacing: .3px;
  border: 1px solid currentColor;
}
/* One hue per meaning, so nothing collides at a glance:
   sand=researching · gold=draft ready · blue=sent · pink=bumped ·
   green=replied · teal=calls · ice=relationship · muted red=closed ·
   ORANGE (pulsing)=something is due · track tags alternate blue/coral. */
.badge.state-Researching { background: rgba(122, 109, 86, .1); color: #6b6151; }
.badge.state-Draft       { background: rgba(184, 145, 47, .14); color: #7a5c14; }
.badge.state-Sent        { background: rgba(36, 84, 158, .1); color: #24549e; }
.badge.state-Bumped      { background: rgba(197, 48, 119, .09); color: #a52a63; }
.badge.state-Replied     { background: var(--green-pale); color: var(--green); }
.badge.state-Call        { background: rgba(15, 118, 110, .11); color: #0f766e; }
.badge.state-Relationship{ background: #f3e8c8; color: #7a5c14; }
.badge.state-Closed, .badge.state-Not { background: rgba(187, 51, 80, .07); color: #a84a5c; }
.badge.due {
  background: rgba(210, 88, 18, .13); color: #b5480c;
  transform: rotate(-2deg);
  animation: due-pulse 2.4s ease-in-out infinite;
}
@keyframes due-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(210, 88, 18, .3); }
  50%      { box-shadow: 0 0 0 5px rgba(210, 88, 18, 0); }
}
.badge.warn {
  background: var(--gold-bright);
  color: #211a10; border-color: #211a10;
}

/* ---------- forms ---------- */
label.field { display: block; margin-bottom: 14px; font-size: 12px; color: var(--gray); font-weight: 600; }
label.field span {
  display: block; margin-bottom: 5px; text-transform: uppercase;
  letter-spacing: .7px; font-size: 10px; font-weight: 600; color: #6f6450;
}
input[type="text"], input[type="date"], input[type="time"], input[type="password"],
input[type="email"], input[type="file"], select, textarea {
  width: 100%; padding: 9px 11px; border: 1.5px solid rgba(33, 26, 16, .6); border-radius: var(--radius);
  font-family: inherit; font-size: 13px; color: var(--ink);
  background: #fffcf2; font-weight: 400;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease), background .15s var(--ease);
}
textarea { resize: vertical; min-height: 74px; line-height: 1.55; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--ink-black);
  background: #fff;
  box-shadow: 3px 3px 0 var(--gold-bright);
}
input::placeholder, textarea::placeholder { color: var(--gray-light); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; }
.form-grid .full { grid-column: 1 / -1; }

/* ---------- modal ---------- */
#modal-root:not(:empty), #picker-root:not(:empty) {
  position: fixed; inset: 0; background: rgba(46, 35, 15, .45); z-index: 50;
  display: flex; align-items: flex-start; justify-content: center;
  overflow-y: auto; padding: 44px 20px;
  animation: fade-in .2s var(--ease);
}
/* The track picker stacks above whatever opened it — usually the contact
   form — so the form underneath survives the pick. */
#picker-root:not(:empty) { z-index: 60; }
#picker-root .modal { max-width: 560px; }
@keyframes fade-in { from { opacity: 0; } }
.modal {
  background: #fffcf2;
  width: 100%; max-width: 780px; padding: 28px 32px;
  border: 2px solid var(--ink-black); border-radius: var(--radius);
  box-shadow: 8px 8px 0 rgba(33, 26, 16, .9);
  animation: modal-in .35s var(--spring) both;
}
@keyframes modal-in { from { opacity: 0; transform: translateY(-14px) scale(.97); } }
.modal h3 {
  font-family: var(--serif); font-style: italic;
  font-size: 24px; font-weight: 700; color: #1c150b; margin-bottom: 16px;
  background: linear-gradient(transparent 62%, rgba(207, 174, 112, .5) 62%, rgba(207, 174, 112, .5) 94%, transparent 94%);
  display: inline-block; padding: 0 5px; margin-left: -5px;
}
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }

/* ---------- toast: stamped in ink ---------- */
#toast:not(:empty) {
  position: fixed; bottom: 26px; left: 50%;
  background: var(--ink-black);
  color: #f1ede2; padding: 12px 22px;
  border: 1.5px solid var(--ink-black); border-left: 5px solid #cfae70;
  border-radius: var(--radius); font-size: 13px; z-index: 100;
  box-shadow: 5px 5px 0 rgba(33, 26, 16, .35); max-width: 580px;
  animation: toast-in .35s var(--spring) both;
}
#toast.error:not(:empty) { border-left-color: #e8798d; }
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 16px) scale(.96); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ---------- misc ---------- */
.mono, pre.output {
  font-family: var(--mono); font-size: 12px;
  background: var(--raised); border: 1.5px solid rgba(33, 26, 16, .5); border-radius: var(--radius);
  padding: 15px; white-space: pre-wrap; max-height: 480px; overflow-y: auto;
  line-height: 1.6; color: #4a3f2c;
}
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.spread { justify-content: space-between; }
.muted { color: #5f5442; font-size: 12.5px; line-height: 1.65; }
.checklist label {
  display: flex; gap: 11px; align-items: flex-start; font-size: 13px;
  margin-bottom: 11px; cursor: pointer; color: var(--ink); font-weight: 400;
  padding: 4px 6px; border-radius: 3px; margin-left: -6px;
  transition: background .16s var(--ease);
}
.checklist label:hover { background: rgba(33, 26, 16, .06); }
.checklist input { margin-top: 3px; accent-color: var(--gold-dark); width: 15px; height: 15px; }
.checklist b { font-weight: 600; color: #1c150b; }
.divider { border: none; border-top: 2px dashed rgba(33, 26, 16, .3); margin: 20px 0; }

.queue-item {
  display: flex; align-items: center; gap: 13px; padding: 12px 0;
  border-bottom: 1px dashed rgba(33, 26, 16, .3); font-size: 13px;
  animation: card-in .34s var(--ease) both;
}
.queue-item:last-child { border-bottom: none; }
.empty { color: var(--gray); font-size: 13px; padding: 24px 0; text-align: center; }

.spinner {
  display: inline-block; width: 13px; height: 13px;
  border: 2px solid rgba(33, 26, 16, .25); border-top-color: var(--gold-dark);
  border-radius: 50%; animation: spin .7s linear infinite;
  vertical-align: -2px; margin-right: 7px;
}
@keyframes spin { to { transform: rotate(360deg); } }

.tabbar { display: flex; gap: 6px; border-bottom: 2px solid var(--ink-black); margin-bottom: 20px; }
.tabbar button {
  position: relative; background: transparent; border: 1.5px solid transparent;
  border-bottom: none; border-radius: 3px 3px 0 0;
  padding: 8px 16px 9px;
  font-family: inherit; font-size: 13px; font-weight: 600; letter-spacing: .2px;
  cursor: pointer; color: #5f5442;
  transition: color .15s var(--ease), background .15s var(--ease), transform .2s var(--spring);
}
.tabbar button:hover { color: #211a10; transform: translateY(-2px); }
.tabbar button.active {
  color: #211a10; background: var(--gold-bright);
  border-color: var(--ink-black);
}
.tabbar button::after { content: none; }

.detail-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; margin-bottom: 8px; }
.kv { font-size: 13px; line-height: 1.85; }
.kv b {
  display: inline-block; min-width: 140px; color: #6f6450;
  font-weight: 600;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .7px;
}

details summary { color: var(--gray); transition: color .16s var(--ease); }
details summary:hover { color: var(--gold-dark); }
details[open] summary { margin-bottom: 4px; }

/* Long free-text cells clip cleanly instead of being cut mid-word. */
td.truncate {
  max-width: 260px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; color: var(--gray);
}

/* Numbers read as figures, not prose. */
td:has(> b), .kv { font-variant-numeric: tabular-nums; }

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(33, 26, 16, .35); border-radius: 2px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: rgba(33, 26, 16, .55); background-clip: content-box; }

/* Respect the OS setting — every animation above is decorative. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  /* Waves, skyline and pennants freeze in place fine; the ship would
     freeze off-screen, so park it in view instead. Movers freeze invisible. */
  .ship-track { animation: none; transform: translateX(14vw); }
  /* Same problem, same answer: park her in view rather than off-stage. */
  body.auth-view .plane-track { animation: none; transform: translateX(18vw); }
  .plane-rig { animation: none; }
  .note, .cloud { display: none; }
  .tile:nth-child(odd), .tile:nth-child(even) { transform: none; }
}

/* The ship's banner already carries this on wider screens. */
.login-help { display: none; }

/* Small screens: keep the waves, drop the busier props. */
@media (max-width: 900px) {
  .ship-track, .plane-track, .pennants, .guitar, .marquee, .note, .cloud,
  .skyline { display: none; }
  /* body.auth-view outranks the line above, so say it again at that weight. */
  body.auth-view .plane-track { display: none; }
  /* She is one of the props dropped above, so the address needs saying here. */
  .login-help { display: block; margin-top: 6px; }
}

/* --- the Claude panel: live streaming drawer ------------------------------ */
#claude-panel { position: fixed; inset: 0; z-index: 70; pointer-events: none; }
#claude-panel[hidden] { display: none; }
/* A small chat window parked above the pill, not a full-height drawer — it
   sits beside the page you are reading instead of covering it. */
.cp-box {
  pointer-events: auto;
  position: absolute; right: 18px; bottom: 72px;
  width: min(384px, calc(100vw - 36px));
  height: min(540px, calc(100vh - 110px));
  display: flex; flex-direction: column; overflow: hidden;
  background: #fffcf2;
  border: 2.5px solid var(--ink-black); border-radius: var(--radius);
  box-shadow: 6px 6px 0 rgba(207, 174, 112, .75);
  animation: cp-in .28s var(--spring);
}
@keyframes cp-in { from { transform: translateY(16px) scale(.98); opacity: 0; } }
.cp-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-bottom: 2px solid var(--ink-black);
}
.cp-titles { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.cp-titles b { font-size: 14px; font-weight: 700; }
#cp-status { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-orb {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 35% 30%, #e8d3a0, #cfae70 60%, #8a6d2f);
  border: 1.5px solid var(--ink-black);
  animation: orb-pulse 1.4s ease-in-out infinite;
}
@keyframes orb-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.8); opacity: .7; } }
#claude-panel.done .cp-orb {
  background: radial-gradient(circle at 35% 30%, #b5e3cb, #35a06e 60%, #17714a);
  animation: none;
}
#claude-panel.failed .cp-orb {
  background: radial-gradient(circle at 35% 30%, #f4c2cc, #d9647c 60%, #a12744);
  animation: none;
}
/* The transcript: every turn stays put, so you can scroll back through the
   conversation instead of watching each answer overwrite the last. */
#cp-thread {
  flex: 1; margin: 0; padding: 12px;
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 10px;
  background: #f8f2e2;
}
#cp-thread:empty::before {
  content: "Ask Claude anything about your CRM — it can see every contact, thread and call.";
  color: var(--gray-light); font-size: 12.5px; line-height: 1.6; padding: 6px 2px;
}
.cp-msg {
  max-width: 88%; padding: 8px 11px; border-radius: var(--radius);
  font-size: 12.5px; line-height: 1.6; white-space: pre-wrap; word-break: break-word;
}
/* You: gold, right-aligned. */
.cp-msg.me {
  align-self: flex-end; background: var(--gold-bright);
  border: 1.5px solid var(--ink-black); box-shadow: 2px 2px 0 rgba(33, 26, 16, .5);
  font-family: var(--sans);
}
/* Claude: ivory, left-aligned, monospace — replies carry drafts and labelled
   research lines that depend on their own line breaks. */
.cp-msg.claude {
  align-self: flex-start; background: #fff;
  border: 1.5px solid rgba(33, 26, 16, .45);
  font-family: var(--mono); color: #3d3322;
}
/* A task the app kicked off (research, scoring, a draft) rather than something
   typed — labelled so the transcript still reads as one history. */
.cp-msg.task {
  align-self: flex-end; background: transparent;
  border: 1.5px dashed rgba(33, 26, 16, .45);
  font-family: var(--sans); font-size: 11.5px; color: var(--gray);
}
.cp-msg.err {
  align-self: flex-start; background: #fdf0f2;
  border: 1.5px solid var(--red); color: #7d1b30; font-family: var(--sans);
}
/* A live cursor on the reply being written right now. */
#claude-panel:not(.done):not(.failed) .cp-msg.claude:last-child::after {
  content: "▌"; color: var(--gold-dark); animation: cp-blink 1s steps(1) infinite;
}
.cp-msg.claude:empty::before { content: "Thinking…"; color: var(--gray-light); }
@keyframes cp-blink { 50% { opacity: 0; } }
.cp-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; border-top: 1.5px solid rgba(33, 26, 16, .35); font-size: 11.5px;
}
#claude-panel.done #cp-stop, #claude-panel.failed #cp-stop { display: none; }

/* Ask box in the drawer: talk to Claude from anywhere. */
.cp-ask { display: flex; gap: 8px; padding: 10px 12px; border-top: 2px solid var(--ink-black); }
.cp-ask input {
  flex: 1; background: #fff; border: 1.5px solid rgba(33, 26, 16, .6);
  border-radius: var(--radius); color: var(--ink); padding: 9px 12px; font-size: 13px; font-family: var(--sans);
}
.cp-ask input:focus { outline: none; border-color: var(--ink-black); box-shadow: 3px 3px 0 var(--gold-bright); }

/* The pill: a small Claude that lives in the corner of every tab.
   Commodore black, like the sidebar and toast. */
#claude-pill {
  position: fixed; right: 18px; bottom: 18px; z-index: 69;
  display: flex; align-items: center; gap: 9px;
  padding: 9px 15px; border-radius: 999px; cursor: pointer;
  background: var(--ink-black);
  border: 1.5px solid var(--ink-black);
  box-shadow: 3px 3px 0 rgba(207, 174, 112, .8);
  font-size: 12.5px; color: #f1ede2; user-select: none;
  transition: transform .2s var(--spring), box-shadow .15s ease;
}
#claude-pill:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 rgba(207, 174, 112, .9); }
#claude-pill .cp-orb { width: 11px; height: 11px; border-color: rgba(207, 174, 112, .8); }
#claude-pill.idle .cp-orb { animation: none; }
#claude-pill.done-flash { box-shadow: 3px 3px 0 rgba(53, 160, 110, .8); }
#claude-pill.done-flash .cp-orb {
  background: radial-gradient(circle at 35% 30%, #b5e3cb, #35a06e 60%, #17714a);
  animation: none;
}
#claude-pill[hidden] { display: none; }
#pill-time { color: #a3967e; font-family: var(--mono); font-size: 11.5px; }
@media (max-width: 900px) { #claude-pill { display: none; } }

/* --- web mode ------------------------------------------------------------ */
/* The Claude drawer needs a Claude to talk to. On the website that is the
   bridge agent on the student's own PC, so the drawer appears the moment their
   bridge connects and stays hidden until then — copy-prompt covers the gap.
   The desktop-Outlook buttons keep their own web-native path. */
.web-mode:not(.claude-bridge-on) #claude-pill,
.web-mode:not(.claude-bridge-on) #claude-panel,
/* "Open in Outlook" and "Sync Outlook" reach the user's own PC through the
   Outlook bridge agent, exactly like the Claude drawer does, so they appear
   once that bridge connects and stay hidden until then -- the OWA deeplink
   covers the gap. "Create Outlook draft" is the Graph path and stays
   desktop-only. */
.web-mode:not(.outlook-bridge-on) #d-ow,
.web-mode:not(.outlook-bridge-on) #olSyncBtn,
.web-mode #d-outlook { display: none !important; }

/* Setup card for the Claude bridge: the key is shown once, so it gets the
   monospace treatment and room to be selected cleanly. */
.bridge-key {
  font-family: Consolas, monospace; font-size: 12.5px; word-break: break-all;
  background: var(--gold-pale); border: 1.5px dashed var(--gold-dark);
  border-radius: var(--radius); padding: 10px 12px; margin: 8px 0;
  user-select: all;
}
.bridge-steps { margin: 8px 0 0 18px; line-height: 1.75; font-size: 13px; }
.bridge-steps code {
  font-family: Consolas, monospace; font-size: 12px;
  background: #fffcf2; border: 1px solid rgba(33, 26, 16, .25);
  border-radius: 4px; padding: 1px 5px;
}

/* The login gate: one varsity card, front and center. */
.login-gate {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  /* Transparent, not var(--bg): an opaque fill here painted straight over the
     Commodore scene, which is why sign-in sat on bare ivory. The body still
     supplies the same ivory underneath, and the card carries its own, so the
     form reads exactly as before -- the ship just sails behind it now. */
  background: transparent; padding: 20px;
}
/* Pinned to the viewport corner, clear of the card, which can overflow the
   top of a short screen. */
.login-back {
  position: absolute; top: 18px; left: 22px; z-index: 2;
  font-family: var(--display); font-weight: 600; font-size: 15px; letter-spacing: .08em;
  color: var(--gray); text-decoration: none;
}
.login-back:hover { color: var(--ink); }
.login-card {
  width: min(420px, 94vw);
  background: #fffcf2; border: 2px solid var(--ink-black); border-radius: var(--radius);
  box-shadow: 8px 8px 0 rgba(33, 26, 16, .9);
  padding: 36px 36px 26px; text-align: center;
  animation: modal-in .35s var(--spring) both;
}
.login-card h1 { margin-left: 0; }
/* The Commodore mark, standing free. The old circular crop with its gold ring
   was built for a square PHOTO -- run a transparent bust through it and the
   bicorne and both shoulders get sliced off. Contain, don't cover. */
.login-mrc {
  width: auto; height: 116px;
  object-fit: contain;
  margin-bottom: 14px;
  filter: drop-shadow(4px 4px 0 rgba(33, 26, 16, .18));
}
.login-sub { color: #5f5442; font-size: 13.5px; margin: 14px 0 20px; }
.login-err {
  color: var(--red); font-size: 13px; font-weight: 600;
  background: var(--red-pale); border: 1px solid var(--red); border-radius: var(--radius);
  padding: 8px 12px; margin-bottom: 16px;
}
.login-fine { color: var(--gray-light); font-size: 11px; margin-top: 14px; }
/* Same slot as the error line, but for "your code is still valid" notes. */
.login-err.login-note {
  color: #7a5c14; background: var(--gold-pale); border-color: var(--gold);
}

/* Sign in / Create account tabs. */
.login-tabs {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  margin: 4px 0 16px;
}
.login-tab {
  border: 1.5px solid var(--line-strong); border-radius: var(--radius);
  background: #fffcf2; color: #5f5442;
  padding: 9px 8px; font-family: inherit; font-size: 13.5px; font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.login-tab:hover { background: #f6eed8; }
.login-tab.active {
  background: var(--gold-bright); color: #211a10;
  border-color: var(--ink-black); box-shadow: 2px 2px 0 var(--ink-black);
}

/* The login card's own inputs: full width, centered, comfortable. */
.login-card input, .login-card select {
  width: 100%; text-align: center; font-size: 15px;
}
.login-row { display: grid; grid-template-columns: 1.4fr 1fr; gap: 8px; }

/* Live "do the two passwords match" line under the confirm field. */
.login-match { font-size: 11.5px; font-weight: 600; margin-top: 8px; min-height: 14px; color: var(--gray-light); }
.login-match.ok { color: var(--green); }
.login-match.bad { color: var(--red); }

/* "You're all signed in" checkmark. */
.login-done {
  width: 62px; height: 62px; margin: 0 auto 14px;
  border-radius: 50%; background: var(--gold-bright);
  border: 2px solid var(--ink-black); box-shadow: 3px 3px 0 var(--ink-black);
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; color: #211a10;
  animation: modal-in .4s var(--spring) both;
}

/* Onboarding: the track picker — varsity chips that number themselves in
   the order you pick them (first pick = default lane). */
#ob-tracks, #st-tracks { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ob-track {
  display: flex; align-items: center; gap: 8px;
  border: 1.5px solid rgba(33, 26, 16, .45); border-radius: var(--radius);
  background: #fffcf2; color: var(--ink);
  padding: 9px 12px; font-family: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; text-align: left;
  transition: transform .15s var(--spring), background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.ob-track:hover { transform: translate(-1px, -1px); box-shadow: 2px 2px 0 rgba(33, 26, 16, .5); }
.ob-track.on {
  background: var(--gold-bright); border-color: var(--ink-black);
  box-shadow: 2px 2px 0 var(--ink-black);
}
.ob-num {
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--display); font-weight: 600; font-size: 13px;
  border: 1.5px dashed rgba(33, 26, 16, .35); color: transparent;
}
.ob-track.on .ob-num {
  background: var(--ink-black); color: var(--gold-bright); border-style: solid;
}

/* Track tags. Tracks are user-defined; the two hues alternate by the
   track's position in the Settings list so neighbors read differently. */
/* Track tags carry their own colour inline (see trackStyle in app-core.js),
   so this only fixes the shape they share. */
.badge.track-tag { border: 1px solid; font-weight: 700; letter-spacing: .04em; }
.track-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block;
  border: 1px solid rgba(33, 26, 16, .5);
}

/* Always-reachable way out of a contact, no matter how deep you've scrolled. */
.back-float {
  position: fixed; bottom: 18px; left: 254px; z-index: 40;
  background: #fffcf2;
}
@media (max-width: 900px) { .back-float { left: 14px; } }

/* Studio: the shortlist marker — the gold stamp, slightly askew. */
.badge.top-pick {
  background: var(--gold-bright);
  color: #211a10; border-color: #211a10;
  transform: rotate(-2deg);
}

/* Contact links under the composer preview. */
.src-list { list-style: none; margin: 0; padding: 0; font-size: 12.5px; line-height: 2; }

/* Verification flags: this person appears to have left the firm. */
.badge.left-flag { background: rgba(210, 88, 18, .13); color: #b5480c; }

/* Dashboard week view: a quiet day header above each day's chats. */
.week-day { margin-bottom: 6px; }
.week-day-label {
  font-size: 11px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase;
  color: var(--gold-dark); margin: 12px 0 6px;
}
.week-day:first-child .week-day-label { margin-top: 0; }

/* ---------- tutorial: the app as a campaign of levels ---------- */
/* Hero: which level you are on, and how much of the route is cleared. */
.tut-hero { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-top: 18px; }
.tut-kicker {
  font-family: var(--display); font-weight: 600; font-size: 13px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold-dark); margin-bottom: 4px;
}
.tut-hero-title { font-family: var(--serif); font-style: italic; font-weight: 700; font-size: 26px; color: #1c150b; line-height: 1.15; margin-bottom: 4px; }
.tut-progress { min-width: 220px; flex: 0 0 auto; }
.tut-progress-label { font-size: 12px; color: #5f5442; margin-bottom: 6px; text-align: right; }
.tut-bar {
  height: 14px; border: 1.5px solid var(--ink-black); border-radius: 3px;
  background: #fffcf2; box-shadow: 2px 2px 0 var(--ink-black); overflow: hidden;
}
.tut-bar i { display: block; height: 100%; background: var(--gold-bright); transition: width .6s var(--spring); }

/* The map: one tile per level. Active = the one open below; done = cleared. */
.tut-map { display: grid; grid-template-columns: repeat(auto-fill, minmax(142px, 1fr)); gap: 10px; margin-bottom: 18px; }
.tut-lvl {
  text-align: left; cursor: pointer; font-family: inherit;
  background: #fffcf2; border: 1.5px solid var(--ink-black); border-radius: var(--radius);
  padding: 10px 12px 9px; box-shadow: 3px 3px 0 var(--ink-black);
  display: grid; gap: 1px; transition: transform .2s var(--spring), box-shadow .2s var(--spring), background .15s var(--ease);
  animation: tile-pop .55s var(--spring) both; animation-delay: calc(var(--i, 0) * 45ms);
}
.tut-lvl:hover { transform: translate(-2px, -2px); box-shadow: 5px 5px 0 var(--ink-black); }
.tut-lvl .n { font-family: var(--display); font-weight: 600; font-size: 22px; line-height: 1; color: var(--gold-dark); }
.tut-lvl .t { font-weight: 700; font-size: 12.5px; color: #1c150b; }
.tut-lvl .s { font-size: 10px; letter-spacing: .5px; text-transform: uppercase; color: #6f6450; font-weight: 600; margin-top: 3px; }
.tut-lvl.done { background: #f3e6c4; }
.tut-lvl.done .n { color: #1c150b; }
.tut-lvl.done .s { color: #1f7a3a; }
.tut-lvl.active { background: var(--gold-bright); transform: translate(-2px, -2px); box-shadow: 5px 5px 0 var(--ink-black); }
.tut-lvl.active .n { color: #1c150b; }

.tut-intro { font-size: 13.5px; color: #3d3322; max-width: 760px; margin: 4px 0 6px; line-height: 1.55; }

/* The screenshot, with numbered arrows dropped on it by percentage so they
   land on the same spot at any width. The arrow's TIP sits at the pin's
   x/y (an edge of the element) and the whole thing rotates about that tip,
   so the tail and its number always trail off into whitespace instead of
   covering the thing being explained. */
.tut-fig {
  position: relative; margin: 14px 0 12px; overflow: hidden;
  border: 1.5px solid var(--ink-black); border-radius: var(--radius);
  background: #fffcf2; box-shadow: 4px 4px 0 rgba(33, 26, 16, .85);
}
.tut-fig img { display: block; width: 100%; height: auto; }
.tut-arrow i, .tut-keys .k {
  display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%;
  background: var(--gold-bright); color: #1c150b; border: 1.5px solid var(--ink-black);
  box-shadow: 2px 2px 0 var(--ink-black);
  font-family: var(--mono); font-style: normal; font-weight: 700; font-size: 11px; line-height: 1;
}
.tut-arrow {
  position: absolute; width: 0; height: 0; pointer-events: none;
  transform: rotate(var(--rot, 0deg)); transform-origin: 0 0;
  animation: tut-arrow-in .5s var(--spring) both; animation-delay: .25s;
}
/* Drawn tip-left: tip at (7,12), tail at (55,7). Offsets put the tip on the origin. */
.tut-arrow svg { position: absolute; left: -7px; top: -12px; width: 60px; height: 24px; overflow: visible; }
.tut-arrow path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.tut-arrow .halo { stroke: #fffcf2; stroke-width: 5.5px; }
.tut-arrow .ink { stroke: #1c150b; stroke-width: 2.2px; }
/* The number rides the tail and counter-rotates so it always reads upright. */
.tut-arrow i {
  position: absolute; left: 48px; top: -5px;
  transform: translate(-50%, -50%) rotate(calc(var(--rot, 0deg) * -1));
}
@keyframes tut-arrow-in {
  from { opacity: 0; transform: rotate(var(--rot, 0deg)) scale(.5); }
  to   { opacity: 1; transform: rotate(var(--rot, 0deg)) scale(1); }
}
.tut-keys { list-style: none; padding: 0; margin: 0 0 22px; display: grid; gap: 9px; }
.tut-keys li { display: flex; align-items: flex-start; gap: 11px; font-size: 13px; line-height: 1.5; color: #3d3322; }
.tut-keys .k { flex: none; margin-top: 1px; }

.tut-actions {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 14px; border-top: 1px dashed rgba(33, 26, 16, .3);
}
/* A quiet button for the ivory column (.btn-ghost is tuned for the black sidebar). */
.btn-ghost-ink { background: transparent; border-color: rgba(33, 26, 16, .35); color: #5f5442; box-shadow: none; }
.btn-ghost-ink:hover { background: #f3e6c4; color: #1c150b; border-color: var(--ink-black); }

.tut-boss { text-align: center; padding: 30px 22px; }
.tut-boss .big { font-family: var(--serif); font-style: italic; font-weight: 700; font-size: 32px; color: #1c150b; line-height: 1.1; }

@media (max-width: 640px) {
  .tut-hero { flex-direction: column; align-items: stretch; }
  .tut-progress-label { text-align: left; }
}
