/* ============================================================================
   Team Dashboard
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  --bg:            #0a0d14;
  --bg-2:          #0e131d;
  --panel:         rgba(255, 255, 255, 0.035);
  --panel-2:       rgba(255, 255, 255, 0.06);
  --panel-solid:   #141a26;
  --line:          rgba(255, 255, 255, 0.09);
  --line-2:        rgba(255, 255, 255, 0.16);
  --txt:           #e8edf6;
  --txt-2:         #9aa7bd;
  --txt-3:         #63708a;
  --accent:        #22d3ee;
  --accent-2:      #a78bfa;
  --gold:          #fbbf24;
  --silver:        #cbd5e1;
  --bronze:        #d08b5a;
  --good:          #34d399;
  --warn:          #fb923c;
  --bad:           #f87171;
  --track:         rgba(255, 255, 255, 0.07);

  --r-sm: 8px;
  --r:    13px;
  --r-lg: 20px;

  --shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
  --font: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "Cascadia Mono", ui-monospace, "SF Mono", Consolas, monospace;
}

:root[data-theme="light"] {
  --bg:            #eef1f6;
  --bg-2:          #e4e9f1;
  --panel:         rgba(255, 255, 255, 0.72);
  --panel-2:       rgba(255, 255, 255, 0.95);
  --panel-solid:   #ffffff;
  --line:          rgba(15, 25, 45, 0.10);
  --line-2:        rgba(15, 25, 45, 0.20);
  --txt:           #101828;
  --txt-2:         #4a5670;
  --txt-3:         #78849c;
  --accent:        #0891b2;
  --accent-2:      #7c3aed;
  --track:         rgba(15, 25, 45, 0.09);
  --shadow: 0 14px 36px rgba(20, 34, 61, 0.14);
}

/* ---------------------------------------------------------------- reset */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--txt);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-size: 14px;
  line-height: 1.5;
}
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(1100px 620px at 12% -8%,  rgba(34, 211, 238, 0.13), transparent 62%),
    radial-gradient(1000px 560px at 92% 4%,   rgba(167, 139, 250, 0.13), transparent 60%),
    radial-gradient(1200px 700px at 50% 108%, rgba(52, 211, 153, 0.08), transparent 62%);
}
:root[data-theme="light"] body::before { opacity: 0.55; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; padding: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -0.015em; }
a { color: var(--accent); }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--txt-3); background-clip: content-box; }

/* ---------------------------------------------------------------- shell */
#app { position: relative; z-index: 1; min-height: 100%; display: flex; flex-direction: column; }

/* The right-hand side grew an access chip and a sync chip, so the bar has to
   wrap rather than squeeze the brand into four lines on a narrow window. */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 22px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 11px; margin-right: 4px; flex: none; }
/* The studio mark sits on a plate that stays dark in both themes. The logo
   carries a white chevron of its own, which simply disappears on a light
   background — so rather than tint the artwork, it keeps the surface it was
   drawn for. */
.brand-mark {
  width: 32px; height: 32px; border-radius: 9px; flex: none;
  background: #0b1017;
  display: grid; place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 0 18px rgba(34, 211, 238, 0.18);
}
.brand-mark img { display: block; width: 24px; height: 24px; }
.brand-txt { line-height: 1.15; }
.brand-txt strong { display: block; font-size: 14px; letter-spacing: -0.02em; white-space: nowrap; }
.brand-txt span { font-size: 10.5px; color: var(--txt-3); text-transform: uppercase; letter-spacing: 0.14em; white-space: nowrap; }

.nav { display: flex; gap: 3px; padding: 3px; background: var(--panel); border: 1px solid var(--line); border-radius: 11px; flex: none; }
.nav button {
  padding: 7px 14px; border-radius: 8px; font-size: 12.5px; font-weight: 550;
  color: var(--txt-2); transition: background 0.15s, color 0.15s; white-space: nowrap;
}
.nav button:hover { color: var(--txt); background: var(--panel-2); }
.nav button.on { background: var(--txt); color: var(--bg); }
/* "There is something new in there", and nothing more. A count here would
   compete with the page you are already reading; the figure itself is on the
   Project Feedback page. */
.nav button { display: inline-flex; align-items: center; gap: 6px; }
.nav-dot {
  width: 6px; height: 6px; border-radius: 99px; flex: none;
  background: var(--warn); box-shadow: 0 0 7px var(--warn);
}
.nav button.on .nav-dot { background: var(--bg); box-shadow: none; opacity: 0.55; }

.spacer { flex: 1 1 auto; }
.topbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 12.5px; font-weight: 550; color: var(--txt-2);
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.08s;
  white-space: nowrap;
}
.btn:hover { background: var(--panel-2); color: var(--txt); border-color: var(--line-2); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.38; pointer-events: none; }
.btn.primary { background: linear-gradient(140deg, var(--accent), #0ea5b7); color: #04070d; border-color: transparent; font-weight: 650; }
.btn.primary:hover { filter: brightness(1.09); color: #04070d; }
.btn.danger { color: var(--bad); border-color: rgba(248, 113, 113, 0.3); }
.btn.danger:hover { background: rgba(248, 113, 113, 0.14); color: var(--bad); }
.btn.sm { padding: 5px 10px; font-size: 11.5px; border-radius: 8px; }
.btn.icon { padding: 7px; width: 30px; height: 30px; justify-content: center; }
.btn.icon.sm { width: 25px; height: 25px; padding: 0; font-size: 12px; }
.btn.on { background: var(--accent); color: #04070d; border-color: transparent; font-weight: 650; }
.btn.on.master { background: linear-gradient(135deg, var(--gold), #f59e0b); color: #1a1204; }

.toggle-master { border-color: rgba(251, 191, 36, 0.34); color: var(--gold); }
.toggle-master:hover { background: rgba(251, 191, 36, 0.14); color: var(--gold); }

/* ---------------------------------------------------------------- inputs */
.field {
  width: 100%; padding: 8px 11px; border-radius: 9px;
  background: var(--panel); border: 1px solid var(--line); color: var(--txt);
  outline: none; transition: border-color 0.15s, background 0.15s;
}
.field:focus { border-color: var(--accent); background: var(--panel-2); }
.field.sm { padding: 5px 9px; font-size: 12.5px; border-radius: 7px; }
textarea.field { resize: vertical; min-height: 68px; }
select.field { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--txt-3) 50%), linear-gradient(135deg, var(--txt-3) 50%, transparent 50%); background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 28px; }
option { background: var(--panel-solid); color: var(--txt); }
/* Chrome paints an optgroup's LABEL from the element's own background, not the
   select's — so without this the group headings in the skill-tag picker come
   out white-on-white in the dark theme. The nested option rule is needed too,
   because options inside a group inherit from the group, not from select. */
optgroup {
  background: var(--panel-solid); color: var(--txt-3);
  font-style: normal; font-weight: 700;
}
optgroup option { background: var(--panel-solid); color: var(--txt); font-weight: 400; }
label.lbl { display: block; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.13em; color: var(--txt-3); margin-bottom: 5px; font-weight: 600; }

/* ---------------------------------------------------------------- layout */
/* Full browser width, less a breathing margin. Deliberately uncapped: the
   timeline columns are proportional, so every extra pixel buys readability. */
main { flex: 1; padding: 26px 26px 90px; width: 100%; margin: 0 auto; }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
.page-head h1 { font-size: 25px; }
.page-head .sub { color: var(--txt-3); font-size: 13px; }

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px;
  backdrop-filter: blur(12px);
}
.eyebrow { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.16em; color: var(--txt-3); font-weight: 650; }

/* ---------------------------------------------------------------- roster */
.roster-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }

.member-card {
  position: relative; overflow: hidden; text-align: left;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px;
  transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s;
  display: block; width: 100%;
}
.member-card:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--shadow); }
.member-card::after {
  content: ""; position: absolute; inset: -40% -20% auto auto; width: 200px; height: 200px;
  background: radial-gradient(circle, var(--tint), transparent 68%); opacity: 0.16; pointer-events: none;
}
.mc-top { display: flex; align-items: center; gap: 13px; margin-bottom: 16px; }
.avatar {
  width: 46px; height: 46px; border-radius: 13px; flex: none;
  display: grid; place-items: center; font-weight: 700; font-size: 16px; color: #05080e;
  background: linear-gradient(140deg, var(--tint), color-mix(in srgb, var(--tint) 45%, #ffffff));
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.13) inset;
}
.avatar.lg { width: 74px; height: 74px; border-radius: 20px; font-size: 25px; }
.avatar.sm { width: 24px; height: 24px; border-radius: 7px; font-size: 9.5px; }
.mc-name { font-weight: 650; font-size: 15.5px; letter-spacing: -0.01em; }
.mc-role { color: var(--txt-3); font-size: 12px; }
.mc-level {
  margin-left: auto; text-align: right; flex: none;
  font-family: var(--mono); font-size: 11px; color: var(--txt-3);
}
.mc-level b { display: block; font-size: 21px; color: var(--txt); font-family: var(--font); line-height: 1; }
.mc-bars { display: grid; gap: 7px; }
.mc-foot { display: flex; gap: 14px; margin-top: 15px; padding-top: 13px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--txt-3); }
.mc-foot b { color: var(--txt-2); font-weight: 600; }

/* Kit and rate, sat between the bars and the totals. Chips rather than another
   run of text so the eye can pick "2024" out of a grid of cards without
   reading any of them. */
.mc-facts { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 13px; }
.mc-fact {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 2px 8px; border-radius: 99px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.mc-fact .k { font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.09em; font-weight: 800; color: var(--txt-3); }
.mc-fact .v { font-family: var(--mono); font-size: 10.5px; color: var(--txt-2); font-weight: 650; }

.add-member-card {
  border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  min-height: 190px; display: grid; place-items: center; gap: 6px;
  color: var(--txt-3); font-weight: 550; width: 100%;
  transition: border-color 0.16s, color 0.16s, background 0.16s;
}
.add-member-card:hover { border-color: var(--accent); color: var(--accent); background: var(--panel); }
.add-member-card .plus { font-size: 26px; line-height: 1; }

/* ------------------------------------------------------------ mini bars */
.minibar { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: center; }
.minibar .nm { font-size: 11.5px; color: var(--txt-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.minibar .pv { font-family: var(--mono); font-size: 10.5px; color: var(--txt-3); }
.minibar .tr { grid-column: 1 / -1; height: 5px; border-radius: 99px; background: var(--track); overflow: hidden; }
.minibar .fl { height: 100%; border-radius: 99px; transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1); }

/* ---------------------------------------------------------------- hero */
.hero { display: grid; grid-template-columns: minmax(320px, 1.15fr) minmax(280px, 1fr) minmax(240px, 0.85fr); gap: 16px; margin-bottom: 22px; }
@media (max-width: 1180px) { .hero { grid-template-columns: 1fr 1fr; } .hero > :first-child { grid-column: 1 / -1; } }
@media (max-width: 760px)  { .hero { grid-template-columns: 1fr; } }

.hero-id { position: relative; overflow: hidden; }
.hero-id::after {
  content: ""; position: absolute; inset: -60% -30% auto auto; width: 280px; height: 280px;
  background: radial-gradient(circle, var(--tint), transparent 68%); opacity: 0.17; pointer-events: none;
}
.hero-top { display: flex; gap: 16px; align-items: center; }
.hero-name { font-size: 22px; font-weight: 700; letter-spacing: -0.025em; }
.hero-role { color: var(--txt-2); font-size: 13px; }
.hero-title-chip {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 7px;
  padding: 3px 10px; border-radius: 99px; font-size: 11px; font-weight: 650;
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.2), rgba(167, 139, 250, 0.18));
  border: 1px solid rgba(251, 191, 36, 0.32); color: var(--gold);
}
.xp-row { margin-top: 18px; }
.xp-meta { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 7px; }
.xp-lvl { font-size: 12px; color: var(--txt-2); }
.xp-lvl b { font-size: 15px; color: var(--txt); }
.xp-num { font-family: var(--mono); font-size: 11px; color: var(--txt-3); }
.xp-track { height: 10px; border-radius: 99px; background: var(--track); overflow: hidden; position: relative; }
.xp-fill {
  height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 18px rgba(34, 211, 238, 0.45);
  transition: width 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.hero-notes { margin-top: 14px; font-size: 12.5px; color: var(--txt-3); font-style: italic; }

.attr-grid { display: grid; gap: 11px; }
.attr-row { display: grid; grid-template-columns: 76px 1fr 34px; gap: 10px; align-items: center; }
.attr-row .nm { font-size: 11px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--txt-2); font-weight: 600; }
.attr-row .tr { height: 7px; border-radius: 99px; background: var(--track); overflow: hidden; }
.attr-row .fl { height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--accent-2), var(--accent)); transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.attr-row .pv { font-family: var(--mono); font-size: 11px; color: var(--txt-3); text-align: right; }

.stat-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tile { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); padding: 12px 13px; }
.tile .v { font-size: 21px; font-weight: 700; letter-spacing: -0.03em; line-height: 1.15; }
.tile .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.11em; color: var(--txt-3); margin-top: 2px; }
.badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 99px; font-size: 10.5px; font-weight: 600;
  border: 1px solid var(--line-2); color: var(--txt-2);
}
.badge.gold   { color: var(--gold);   border-color: rgba(251, 191, 36, 0.4);  background: rgba(251, 191, 36, 0.11); }
.badge.silver { color: var(--silver); border-color: rgba(203, 213, 225, 0.34); background: rgba(203, 213, 225, 0.09); }
.badge.bronze { color: var(--bronze); border-color: rgba(208, 139, 90, 0.36); background: rgba(208, 139, 90, 0.11); }

/* ------------------------------------------------------- category list */
.group-head { display: flex; align-items: center; gap: 11px; margin: 26px 0 12px; }
.group-head h2 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.15em; color: var(--txt-3); font-weight: 650; }
.group-head .rule { flex: 1; height: 1px; background: var(--line); }

.cat-list { display: grid; gap: 11px; }

.cat {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--panel); overflow: hidden;
  transition: border-color 0.18s;
}
.cat.open { border-color: var(--line-2); }
.cat-header {
  display: grid; grid-template-columns: auto minmax(150px, 250px) 1fr auto auto;
  gap: 15px; align-items: center; width: 100%; padding: 15px 18px; text-align: left;
  transition: background 0.15s;
}
.cat-header:hover { background: var(--panel-2); }
.chev { color: var(--txt-3); transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1); font-size: 11px; }
.cat.open .chev { transform: rotate(90deg); }
.cat-name { font-weight: 620; font-size: 14.5px; letter-spacing: -0.01em; display: flex; align-items: center; gap: 8px; }
.tag-ph { font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; padding: 2px 6px; border-radius: 5px; background: var(--track); color: var(--txt-3); font-weight: 700; }
.tag-prod {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; padding: 2px 6px;
  border-radius: 5px; font-weight: 700;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
}
.cat-sub { font-size: 11.5px; color: var(--txt-3); margin-top: 1px; }
/* The headline figure for the row — sized to be readable at a glance while
   scanning a long list of tracks. */
.cat-pct {
  font-family: var(--mono); font-size: 25px; font-weight: 700;
  letter-spacing: -0.035em; text-align: right; min-width: 72px; line-height: 1.1;
}
.cat-pct.none   { color: var(--txt-3); }
.cat-pct.low    { color: var(--txt-2); }
.cat-pct.mid    { color: var(--accent); }
.cat-pct.high   { color: var(--good); }
.cat-pct.legend { color: var(--gold); }

.cat-xp {
  font-family: var(--mono); font-size: 14px; font-weight: 600;
  color: var(--txt-2); text-align: right; min-width: 116px; line-height: 1.25;
}
.cat-xp b { color: var(--txt); font-weight: 700; }
.cat-xp .unit {
  display: block; font-family: var(--font); font-size: 9.5px; font-weight: 650;
  letter-spacing: 0.16em; color: var(--txt-3); margin-top: 1px;
}

/* --------------------------------------------------- the timeline bar */
.tl-wrap { padding: 0 18px 18px; }
.tl-scroll { overflow-x: auto; overflow-y: hidden; padding-bottom: 6px; }
/* Hold left and drag to pull a wide timeline sideways. The cursor only offers
   it when there is somewhere to go — layoutTimelines() sets can-scrub. */
.tl-scroll.can-scrub { cursor: grab; }
.tl-scroll.scrubbing { cursor: grabbing; user-select: none; }
.tl-scroll.scrubbing * { cursor: grabbing; }
/* Width is set by layoutTimelines() once the real container width is known. */
.tl-inner { width: 100%; }

.tl-markers { display: flex; height: 20px; align-items: flex-end; margin-bottom: 6px; }
.tl-marker { position: relative; flex: none; }
.tl-marker i {
  position: absolute; right: -5px; bottom: 0;
  width: 10px; height: 10px; border-radius: 99px; background: var(--marker, var(--gold));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bg) 70%, transparent), 0 0 12px var(--marker, var(--gold));
  animation: pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes pop { from { transform: scale(0); } to { transform: scale(1); } }

.tl-bar {
  display: flex; height: 34px; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--line); background: var(--track);
}
.tl-seg {
  position: relative; flex: none; min-width: 2px;
  background: var(--segTrack); overflow: hidden;
  border-right: 1px solid color-mix(in srgb, var(--bg) 55%, transparent);
  transition: filter 0.15s;
}
.tl-seg:last-child { border-right: none; }
.tl-seg-fill {
  position: absolute; inset: 0 auto 0 0; width: 0;
  background: linear-gradient(180deg, color-mix(in srgb, var(--segColor) 88%, #ffffff), var(--segColor));
  transition: width 0.65s cubic-bezier(0.22, 1, 0.36, 1);
}
.tl-seg-fill::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 50%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), transparent);
}
.tl-seg.is-mastered .tl-seg-fill { box-shadow: inset 0 0 22px rgba(255, 255, 255, 0.4); }
.tl-seg .tl-seg-pct {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  color: #04070d; opacity: 0; transition: opacity 0.15s; mix-blend-mode: luminosity;
}
.tl-seg:hover .tl-seg-pct { opacity: 1; }
.tl-seg:hover { filter: brightness(1.15); }
.tl-seg.focus { outline: 2px solid var(--txt); outline-offset: -2px; }

.tl-axis { display: flex; margin-top: 4px; }
.tl-axis-cell { flex: none; padding-right: 10px; min-width: 0; }
/* The label now carries a unit ("27% of score") because width no longer means
   worth, so it can outrun a narrow cell. Clip rather than wrap — the cell has
   one line of room and the full text is on the cell's tooltip. */
.tl-axis-cell .w {
  font-family: var(--mono); font-size: 9.5px; color: var(--txt-3); letter-spacing: 0.04em;
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* --------------------------------------------------- section columns */
.tl-cols { display: flex; gap: 0; margin-top: 12px; align-items: flex-start; }
.tl-col { flex: none; padding: 0 12px 0 0; min-width: 0; }
.tl-col-head { border-top: 2px solid var(--colColor); padding-top: 8px; margin-bottom: 8px; }
.tl-col-title { font-weight: 650; font-size: 12.5px; letter-spacing: -0.005em; line-height: 1.3; }
.tl-col-meta { display: flex; align-items: center; gap: 6px; margin-top: 4px; flex-wrap: wrap; }
.chip-w {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700; letter-spacing: 0.03em;
  padding: 1px 6px; border-radius: 5px;
  background: color-mix(in srgb, var(--colColor) 20%, transparent);
  color: var(--colColor); border: 1px solid color-mix(in srgb, var(--colColor) 34%, transparent);
}
.chip-tag { font-size: 9px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--txt-3); }

/* --------------------------------------------- production subcategories */
/* A quiet divider, not a second heading. The section title above it is the
   thing being scored; these only tell an artist which discipline the skills
   under them belong to, so they stay lighter than everything around them.
   A group renders with no heading at all when the category is General, so
   none of this applies there. */
.sub-head {
  display: flex; align-items: baseline; gap: 6px;
  margin: 10px 0 3px; padding-bottom: 3px;
  border-bottom: 1px solid color-mix(in srgb, var(--colColor) 22%, transparent);
}
.sub-head:first-child { margin-top: 2px; }
.sub-name {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em;
  color: color-mix(in srgb, var(--colColor) 78%, var(--txt-3));
  overflow-wrap: break-word; min-width: 0;
}
.sub-count { font-family: var(--mono); font-size: 9px; color: var(--txt-3); margin-left: auto; flex: none; }
.sub-head.is-done .sub-count { color: var(--gold); }

.skill-list { display: grid; gap: 2px; }
.skill {
  display: grid; grid-template-columns: 1fr auto; gap: 6px; align-items: center;
  padding: 3px 5px; border-radius: 6px; min-height: 24px;
  transition: background 0.13s;
}
.skill:hover { background: var(--panel-2); }
/* break-word only when a single word genuinely cannot fit, never mid-word
   just because the column is tight */
/* One colour for every skill, whatever its rank. The label answers "which
   skill is this"; the pips beside it answer "how far along". Tinting the text
   as well made a column read as three tiers of importance when all it was
   showing was progress, and the un-started skills — the ones worth noticing —
   were the faintest thing on the page. */
.skill-name { font-size: 11.5px; color: var(--txt-2); line-height: 1.35; overflow-wrap: break-word; }

/* A proportional column can be genuinely narrow (a value-1 stage next to a
   value-5 one). Below the threshold the pips drop under the name so the label
   gets the full column width instead of ~55px. */
.tl-col.narrow .skill { grid-template-columns: 1fr; gap: 1px; padding: 4px 5px 5px; }
.tl-col.narrow .skill .pips { justify-content: flex-start; }

/* rank pips */
.pips { display: flex; gap: 2px; align-items: center; flex: none; }
.pip {
  width: 9px; height: 9px; border-radius: 2.5px;
  background: var(--track); border: 1px solid transparent;
  transition: background 0.13s, transform 0.1s;
}
.pip.on { background: var(--colColor, var(--accent)); }
.editable .pip { cursor: pointer; }
.editable .pip:hover { transform: scale(1.32); border-color: var(--txt); }

.tl-col-actions { display: flex; gap: 4px; margin-top: 8px; flex-wrap: wrap; }
.tl-empty { font-size: 11px; color: var(--txt-3); font-style: italic; padding: 4px 5px; }

/* Master Edit — the studio-wide subcategory list */
.sub-rows { display: grid; gap: 4px; }
.sub-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px; align-items: center; }
.sub-row .help-note { margin: 0; text-align: right; }
/* ---------------------------------------------------------------- video */
/* The link out to a training video. Deliberately an <a>, so it keeps every
   behaviour a link has — middle-click, copy address, and getting past a
   popup blocker — while looking like the buttons around it. */
.watch-btn {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  border-color: color-mix(in srgb, var(--accent) 42%, var(--line));
  color: var(--accent);
}
.watch-btn:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: var(--accent);
}
.cm-watch { display: flex; gap: 8px; flex-wrap: wrap; margin: 2px 0 12px; }

/* Marks a thread that belongs to a stage rather than to a skill. Quiet — it
   is a clarification, not a category of its own. */
.cm-kind, .notif-kind {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--txt-3); vertical-align: 2px; margin-left: 5px;
}

/* The marker on a name that carries a video. Same size and rhythm as the
   comment flag it sits beside, one shade quieter — a video is a standing
   fact about the skill, not something new to attend to. */
/* The play glyph beside a name with training behind it, and the tick it wears
   once the person has watched it. Small and low-contrast on purpose: it marks
   a name, it is not a second thing to read. */
.video-flag {
  font-size: 8px; margin-left: 4px; vertical-align: 1px;
  color: color-mix(in srgb, var(--accent) 70%, var(--txt-3));
  white-space: nowrap;
}
.video-flag.seen { color: var(--good); }
.video-flag i { font-style: normal; font-size: 9px; margin-left: 1px; }

/* The header of a skill popup: what it is on the left, whether the video has
   been watched on the right — the corner the eye lands on last. */
.cm-head { display: flex; align-items: flex-start; gap: 12px; }
.cm-head > div:first-child { flex: 1 1 auto; min-width: 0; }
.watched-tog {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 5px 11px 5px 8px; border-radius: 99px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 11.5px; font-weight: 600; color: var(--txt-3);
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.watched-tog:hover { color: var(--txt); border-color: var(--line-2); background: var(--panel-2); }
.watched-tog.on {
  color: var(--good); border-color: rgba(52, 211, 153, 0.42);
  background: rgba(52, 211, 153, 0.1);
}
.watched-tog .wk-tick { pointer-events: none; }
.watched-tog.on .wk-tick { background: var(--good); border-color: var(--good); color: var(--bg); }
.tl-col-title.is-link {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; text-align: left; width: 100%;
}
.tl-col-title.is-link:hover { color: var(--accent); }

.mini-acts { display: flex; gap: 2px; }
.mini-acts button {
  width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center;
  font-size: 10px; color: var(--txt-3); border: 1px solid transparent; transition: background 0.12s, color 0.12s;
}
.mini-acts button:hover { background: var(--panel-2); color: var(--txt); border-color: var(--line); }
.mini-acts button.del:hover { color: var(--bad); border-color: rgba(248, 113, 113, 0.32); background: rgba(248, 113, 113, 0.1); }

/* ---------------------------------------------------------- master edit */
.master-banner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 13px 18px; border-radius: var(--r);
  background: linear-gradient(100deg, rgba(251, 191, 36, 0.13), rgba(251, 191, 36, 0.03));
  border: 1px solid rgba(251, 191, 36, 0.28); margin-bottom: 18px;
}
.master-banner .t { font-weight: 650; color: var(--gold); font-size: 13px; }
.master-banner .d { font-size: 12px; color: var(--txt-2); }

.me-cat { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--panel); margin-bottom: 12px; overflow: hidden; }
.me-cat-head { display: grid; grid-template-columns: auto 1fr auto auto auto; gap: 11px; align-items: center; padding: 13px 16px; border-bottom: 1px solid var(--line); }
.me-cat-head .grip { color: var(--txt-3); font-size: 13px; cursor: grab; }
.me-body { padding: 14px 16px 16px; }

.me-sec {
  border: 1px solid var(--line); border-radius: var(--r); background: var(--panel);
  margin-bottom: 9px; overflow: hidden;
}
.me-sec.dragging { opacity: 0.4; }
.me-sec.drop-before { box-shadow: 0 -3px 0 var(--accent); }
.me-sec.drop-after  { box-shadow: 0  3px 0 var(--accent); }
/* Name and video link share the row, because the name field alone was running
   to most of a very wide screen for text that is rarely more than four words.
   Minmax on both so a narrow window squeezes them instead of scrolling. */
.me-sec-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1.4fr) minmax(0, 1fr) 120px 118px auto auto;
  gap: 9px; align-items: center; padding: 9px 12px;
  border-left: 4px solid var(--secColor);
}
.me-sec-head .grip { cursor: grab; color: var(--txt-3); padding: 0 2px; }
.me-skills { padding: 4px 12px 12px 30px; display: grid; gap: 4px; }
.me-skills.is-banded { padding-left: 12px; gap: 0; }
.me-skill {
  display: grid;
  grid-template-columns: auto minmax(0, 1.4fr) minmax(0, 1fr) 140px auto;
  gap: 8px; align-items: center; border-radius: 6px;
}
/* Quiet when empty, tinted when it holds a link — so a column of these shows
   at a glance how much of a track still has no video against it. */
.vid-field {
  font-family: var(--mono); font-size: 10.5px;
  color: var(--txt-3); border-style: dashed;
}
.vid-field.on {
  color: color-mix(in srgb, var(--accent) 82%, var(--txt));
  border-style: solid;
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line));
}
.vid-field:focus { border-style: solid; }
.me-skill .grip { cursor: grab; color: var(--txt-3); padding: 0 2px; font-size: 11px; line-height: 1; }
.me-skill:hover .grip { color: var(--txt-2); }
.me-skill.dragging { opacity: 0.4; }
.me-skill.drop-before { box-shadow: 0 -2px 0 var(--accent); }
.me-skill.drop-after  { box-shadow: 0  2px 0 var(--accent); }

/* ---- subcategory bands in Master Edit ----
   The same headings the timeline prints, turned into containers. They read as
   dividers first and controls second, so they borrow the timeline's caption
   styling rather than inventing a second look for the same idea. */
.me-band { border-left: 2px solid var(--line); padding-left: 10px; margin: 2px 0 8px; }
.me-band-head { display: flex; align-items: baseline; gap: 7px; padding: 4px 0 4px 2px; }
.me-band-name {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em;
  color: color-mix(in srgb, var(--secColor) 72%, var(--txt-3));
}
.me-band.is-unfiled { border-left-style: dashed; }
.me-band.is-unfiled .me-band-name { color: var(--txt-3); }
.me-band-count { font-family: var(--mono); font-size: 9px; color: var(--txt-3); }
.me-band-add {
  margin-left: auto; width: 18px; height: 18px; border-radius: 5px; flex: none;
  display: grid; place-items: center; font-size: 12px; line-height: 1;
  color: var(--txt-3); border: 1px solid transparent; background: none; cursor: pointer;
}
.me-band-add:hover { background: var(--panel-2); color: var(--txt); border-color: var(--line); }
.me-band-body { display: grid; gap: 4px; }
.me-band-hint { font-size: 10.5px; color: var(--txt-3); font-style: italic; padding: 3px 2px; }

/* An empty band is a slot: visible, slim, and obviously a target. Hiding it
   until a drag began made the whole mechanism undiscoverable — you cannot aim
   at something you have never seen. */
.me-band.is-empty { border-left-style: dashed; margin-bottom: 3px; }
.me-band.is-empty .me-band-head { padding: 2px 0 2px 2px; }
.me-band.is-empty .me-band-name { opacity: 0.72; }
.me-band.is-empty .me-band-hint { font-size: 10px; font-style: italic; color: var(--txt-3); opacity: 0.75; }
.me-band.is-empty:hover { border-left-color: color-mix(in srgb, var(--secColor) 55%, var(--line)); }
.me-band.is-empty:hover .me-band-name,
.me-band.is-empty:hover .me-band-hint { opacity: 1; }

/* Unfiled is not a destination you choose, so an empty one would just be a
   row of noise under every stage. It appears when it holds something, or
   while a drag is in flight and you might want to send something back to it. */
.me-band.is-empty.is-unfiled { display: none; }
body.dnd-skill .me-band.is-empty.is-unfiled { display: block; }
body.dnd-skill .me-band { border-left-color: color-mix(in srgb, var(--secColor) 45%, var(--line)); }
.me-band.drop-into {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-left-color: var(--accent);
}

.weight-picker { display: flex; align-items: center; gap: 5px; }
.weight-picker .pips { gap: 3px; }
.weight-picker .pip { width: 11px; height: 11px; cursor: pointer; }
.weight-picker .lbl-w { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--txt-3); font-weight: 650; }

.add-inline {
  display: flex; align-items: center; gap: 7px; margin-top: 7px;
}
.add-inline .field { flex: 1; }

/* ---------------------------------------------------------------- modal */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(4, 7, 13, 0.72); backdrop-filter: blur(7px);
  display: grid; place-items: center; padding: 24px;
  animation: fade 0.16s ease;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal {
  width: 100%; max-width: 480px; max-height: 86vh; overflow: auto;
  background: var(--panel-solid); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); padding: 22px; box-shadow: var(--shadow);
  animation: rise 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
:root[data-theme="light"] .modal { background: #ffffff; }
.modal.wide { max-width: 660px; }
@keyframes rise { from { transform: translateY(12px) scale(0.985); opacity: 0; } to { transform: none; opacity: 1; } }
.modal h3 { font-size: 17px; margin-bottom: 4px; }
.modal .m-sub { color: var(--txt-3); font-size: 12.5px; margin-bottom: 18px; }
.modal .m-row { margin-bottom: 13px; }
.modal .m-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.modal .m-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px; }
.swatches { display: flex; gap: 7px; flex-wrap: wrap; }
.swatch { width: 26px; height: 26px; border-radius: 8px; border: 2px solid transparent; transition: transform 0.12s; }
.swatch:hover { transform: scale(1.12); }
.swatch.on { border-color: var(--txt); }

/* ---------------------------------------------------------------- toast */
#toast-root { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 120; display: grid; gap: 8px; justify-items: center; }
.toast {
  padding: 10px 17px; border-radius: 11px; font-size: 12.5px; font-weight: 550;
  background: var(--panel-solid); border: 1px solid var(--line-2);
  box-shadow: var(--shadow); animation: rise 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
.toast.good { border-color: rgba(52, 211, 153, 0.42); color: var(--good); }
.toast.bad  { border-color: rgba(248, 113, 113, 0.42); color: var(--bad); }

/* ------------------------------------------------------- access + sync */
.lock-mini { font-size: 10px; opacity: 0.75; }

.sync-chip { gap: 6px; }
.sync-chip .dot-led, .sync-status .dot-led {
  width: 7px; height: 7px; border-radius: 99px; flex: none;
  background: var(--txt-3); box-shadow: 0 0 8px currentColor;
}
.sync-chip.good, .sync-status.good { color: var(--good); border-color: rgba(52, 211, 153, 0.34); }
.sync-chip.good .dot-led, .sync-status.good .dot-led { background: var(--good); }
.sync-chip.warn, .sync-status.warn, .btn.warn-chip { color: var(--warn); border-color: rgba(251, 146, 60, 0.38); }
.sync-chip.warn .dot-led, .sync-status.warn .dot-led { background: var(--warn); }
.sync-chip.good:hover { background: rgba(52, 211, 153, 0.12); color: var(--good); }
.sync-chip.warn:hover, .btn.warn-chip:hover { background: rgba(251, 146, 60, 0.14); color: var(--warn); }

.sync-status { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 550; }
.pill-warn {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  padding: 1px 5px; border-radius: 4px; background: rgba(251, 146, 60, 0.2); color: var(--warn);
}

.publish-banner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; border-radius: var(--r); margin-bottom: 18px;
  background: linear-gradient(100deg, rgba(251, 146, 60, 0.14), rgba(251, 146, 60, 0.03));
  border: 1px solid rgba(251, 146, 60, 0.32);
}
.publish-banner .t { font-weight: 650; color: var(--warn); font-size: 13px; }
.publish-banner .d { font-size: 12px; color: var(--txt-2); margin-top: 2px; }

/* ------------------------------------------------------------ comments */
/* The skill row's label is a button now — comments hang off every skill. */
button.skill-name {
  text-align: left; width: 100%; display: flex; align-items: baseline; gap: 5px;
  border-radius: 4px; transition: color 0.13s;
}
button.skill-name:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }

.cm-flag {
  flex: none; display: inline-grid; place-items: center;
  width: 13px; height: 13px; border-radius: 99px;
  font-size: 9px; font-weight: 800; line-height: 1;
  background: rgba(251, 191, 36, 0.22); color: var(--gold);
  border: 1px solid rgba(251, 191, 36, 0.45);
  vertical-align: middle; margin-left: 4px;
}
.cm-flag.has-admin { background: rgba(167, 139, 250, 0.22); color: var(--accent-2); border-color: rgba(167, 139, 250, 0.5); }
.cm-flag.unread { animation: flagpulse 1.9s ease-in-out infinite; }
@keyframes flagpulse {
  0%, 100% { box-shadow: 0 0 0 0 currentColor; }
  50%      { box-shadow: 0 0 0 3px transparent; }
}

.cm-modal .cm-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 6px; }
@media (max-width: 620px) { .cm-modal .cm-cols { grid-template-columns: 1fr; } }
.cm-col .eyebrow { margin-bottom: 8px; display: block; }
.cm-stream { display: grid; gap: 7px; align-content: start; max-height: 38vh; overflow: auto; padding-right: 4px; }
.cm-empty { font-size: 11.5px; color: var(--txt-3); font-style: italic; padding: 6px 0; }

.cm-item {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel); padding: 8px 10px; border-left: 3px solid var(--line-2);
}
.cm-item.admin { border-left-color: var(--accent-2); background: rgba(167, 139, 250, 0.07); }
.cm-item.member { border-left-color: var(--accent); }
.cm-meta { display: flex; align-items: center; gap: 7px; font-size: 11px; color: var(--txt-3); margin-bottom: 3px; }
.cm-meta b { color: var(--txt-2); font-weight: 650; }
.cm-when { margin-right: auto; }
.cm-text { font-size: 12.5px; color: var(--txt); line-height: 1.5; overflow-wrap: break-word; }
.cm-del {
  width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center; flex: none;
  font-size: 10px; color: var(--txt-3); transition: background 0.12s, color 0.12s;
}
.cm-del:hover { background: rgba(248, 113, 113, 0.14); color: var(--bad); }
/* Same footprint as the delete beside it, so the two read as one pair of row
   actions rather than a button and an afterthought. */
.cm-edit {
  width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center; flex: none;
  font-size: 10px; color: var(--txt-3); transition: background 0.12s, color 0.12s;
}
.cm-edit:hover { background: rgba(34, 211, 238, 0.14); color: var(--accent); }
.cm-locked { font-size: 9px; opacity: 0.5; }
/* Quiet: it qualifies the timestamp, it is not news in its own right. */
.cm-edited {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--txt-3); opacity: 0.75; margin-left: 5px;
}

/* Correcting a posted note, in place. Tinting the whole note while it is open
   is what says "this one is live" — without it, a thread of five notes with a
   textarea somewhere in the middle is hard to read at a glance. */
.cm-item.editing { border-color: var(--accent); background: rgba(34, 211, 238, 0.05); }
.pc-editbox { margin-top: 8px; display: grid; gap: 8px; }
.pc-editbox textarea { min-height: 68px; font-size: 12.5px; }
.pc-editbox .pc-tagpick { margin: 0; }

.cm-add { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.cm-add-head { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }

/* Who this will be signed as. A statement, not a control — the folder the page
   was opened from decides it, so there is nothing here to fill in or pick. */
.cm-as { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--txt-3); }
.cm-as b { color: var(--txt-2); font-weight: 650; }
.cm-as-scope {
  padding: 1px 7px; border-radius: 99px; font-size: 9.5px; font-weight: 750;
  text-transform: uppercase; letter-spacing: 0.06em;
}
.cm-as-scope.member { background: rgba(34, 211, 238, 0.16); color: var(--accent); border: 1px solid rgba(34, 211, 238, 0.34); }
.cm-as-scope.admin { background: rgba(167, 139, 250, 0.16); color: var(--accent-2); border: 1px solid rgba(167, 139, 250, 0.34); }
.cm-add-foot { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.cm-add-foot .help-note { max-width: 320px; }

/* ------------------------------------------------------- notifications */
.notif-card { margin-bottom: 20px; padding: 16px 18px; }
.notif-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.notif-toggle { display: flex; align-items: center; gap: 9px; }
.notif-toggle .chev { transition: transform 0.2s; }
.notif-toggle .chev.down { transform: rotate(90deg); }
.notif-badge {
  padding: 1px 8px; border-radius: 99px; font-size: 10px; font-weight: 750;
  background: rgba(251, 146, 60, 0.2); color: var(--warn); border: 1px solid rgba(251, 146, 60, 0.4);
}
.notif-counts { font-size: 11.5px; color: var(--txt-3); font-family: var(--mono); }
.notif-empty { font-size: 12px; color: var(--txt-3); margin-top: 12px; font-style: italic; }

.notif-list { display: grid; gap: 7px; margin-top: 13px; max-height: 340px; overflow: auto; padding-right: 4px; }
.notif-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: start;
  padding: 9px 11px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--panel);
  border-left: 3px solid var(--accent);
}
.notif-row.admin { border-left-color: var(--accent-2); }
.notif-row.new { background: rgba(251, 146, 60, 0.07); border-color: rgba(251, 146, 60, 0.26); }
.notif-scope {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.11em; font-weight: 800;
  padding: 3px 7px; border-radius: 5px; margin-top: 1px;
  background: var(--track); color: var(--txt-3); white-space: nowrap;
}
.notif-row.admin .notif-scope { background: rgba(167, 139, 250, 0.18); color: var(--accent-2); }
.notif-main { min-width: 0; }
.notif-path { font-size: 11px; color: var(--txt-3); text-align: left; }
.notif-path b { color: var(--txt-2); }
.notif-path:hover { color: var(--accent); }
.notif-path:hover b { color: var(--accent); }
.notif-text { font-size: 12.5px; color: var(--txt); margin-top: 3px; line-height: 1.45; overflow-wrap: break-word; }
.notif-by { font-size: 10.5px; color: var(--txt-3); margin-top: 3px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.notif-by b { color: var(--txt-2); font-weight: 650; }

/* Replies inside the tile of the comment they answer, never a tile of their
   own. The indent and the rule down the left are doing the whole job of saying
   "these belong to the note above" — so they stay quiet: smaller text, no
   border of their own, nothing that competes with the parent for the eye. */
.notif-replies {
  margin: 7px 0 0 2px; display: grid; gap: 6px;
  border-left: 2px solid var(--line-2); padding-left: 9px;
}
.notif-reply .notif-text { font-size: 11.5px; color: var(--txt-2); margin-top: 0; }
.notif-reply .notif-by { font-size: 10px; }
.notif-reply .notif-scope { font-size: 8px; padding: 1px 5px; margin-top: 0; }
.notif-reply.admin .notif-scope { background: rgba(167, 139, 250, 0.18); color: var(--accent-2); }
.notif-reply.member .notif-scope { background: rgba(34, 211, 238, 0.16); color: var(--accent); }
/* An unread answer marks itself even when the note above it has been read. */
.notif-reply.new { border-left: 2px solid var(--warn); margin-left: -11px; padding-left: 9px; }
.notif-main .pc-replylink { margin-top: 6px; }

/* ------------------------------------------------------- screenshots */
.shot-strip { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.shot-strip.posted { margin-top: 7px; }
.shot-hint { font-size: 10.5px; color: var(--txt-3); }
.shot-hint .kbd { margin: 0 1px; }

.shot {
  position: relative; flex: none; display: block; padding: 0; line-height: 0;
  border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line-2); background: var(--track);
  transition: border-color 0.14s, transform 0.1s;
}
.shot img { display: block; width: auto; height: 74px; max-width: 190px; object-fit: cover; }
.shot:hover { border-color: var(--accent); transform: translateY(-1px); }
.shot.staged { border-style: dashed; }
.shot-x {
  position: absolute; top: 3px; right: 3px;
  width: 18px; height: 18px; border-radius: 99px; display: grid; place-items: center;
  font-size: 9px; line-height: 1; color: #fff;
  background: rgba(8, 12, 20, 0.78); border: 1px solid rgba(255, 255, 255, 0.24);
}
.shot-x:hover { background: var(--bad); border-color: var(--bad); }

/* Above the modal, because it is opened from inside one. */
.shot-lightbox {
  position: fixed; inset: 0; z-index: 130; cursor: zoom-out;
  background: rgba(4, 7, 13, 0.9); backdrop-filter: blur(6px);
  display: grid; place-items: center; padding: 32px;
  animation: fade 0.14s ease;
}
.shot-lightbox img {
  max-width: 100%; max-height: 100%;
  border-radius: var(--r); border: 1px solid var(--line-2); box-shadow: var(--shadow);
}
.shot-close {
  position: absolute; top: 18px; right: 22px;
  width: 34px; height: 34px; border-radius: 99px; display: grid; place-items: center;
  color: var(--txt); background: var(--panel-2); border: 1px solid var(--line-2);
}
.shot-close:hover { background: var(--bad); color: #fff; border-color: var(--bad); }

/* ---------------------------------------------------- project feedback */
/* Master and detail. The left column is what you navigate; the right one
   answers it and stays put while you move between scenes. Both scroll on
   their own so a long project list and a long thread never fight over the
   page, and the pane sticks so the note you are reading stays put while you
   run down the list beside it. */
.pf-layout {
  display: grid; grid-template-columns: minmax(280px, 380px) minmax(0, 1fr);
  gap: 16px; align-items: start; margin-top: 4px;
}
.pf-list { min-width: 0; }
.pf-detail {
  min-width: 0; position: sticky; top: 16px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); padding: 16px 18px;
  max-height: calc(100vh - 32px); overflow: auto;
}
.pf-detail-head { border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 4px; }
.pf-detail-head h3 { margin: 0; }

/* Before a scene is picked. Says what the empty half is for rather than
   sitting there blank. */
.pf-blank { text-align: center; padding: 40px 20px; color: var(--txt-3); }
.pf-blank .big { font-size: 30px; opacity: 0.55; margin-bottom: 10px; }
.pf-blank-t { font-size: 13px; font-weight: 600; color: var(--txt-2); margin-bottom: 6px; }
.pf-blank .help-note { max-width: 320px; margin: 0 auto; }

/* Stacked below ~900px: the list first, then the thread it opens. Sticky and
   an inner scroll both stop making sense once they are one column. */
@media (max-width: 900px) {
  .pf-layout { grid-template-columns: 1fr; }
  .pf-detail { position: static; max-height: none; }
}

.proj-list { display: grid; gap: 8px; }

.proj { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); overflow: hidden; }
.proj.open { border-color: var(--line-2); }
.proj-head {
  display: grid; grid-template-columns: auto auto 1fr auto auto;
  gap: 10px; align-items: center; width: 100%; padding: 9px 12px; text-align: left;
  transition: background 0.14s;
}
.proj-head:hover { background: var(--panel-2); }
.proj-head .chev { transition: transform 0.2s; }
.proj-head .chev.down { transform: rotate(90deg); }
.proj-code {
  font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  padding: 2px 6px; border-radius: 5px; white-space: nowrap;
  background: rgba(34, 211, 238, 0.14); color: var(--accent);
  border: 1px solid rgba(34, 211, 238, 0.3);
}
.proj-name { font-size: 12.5px; font-weight: 600; color: var(--txt); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-meta { font-size: 11px; color: var(--txt-3); font-family: var(--mono); white-space: nowrap; }

/* A busy job can carry thirty scenes. Nothing follows this column any more, so
   it can run longer than it used to before it starts scrolling on its own. */
.pc-list { padding: 4px 12px 12px; display: grid; gap: 10px; max-height: 60vh; overflow: auto; }
.pc-group-head {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--txt-3); font-weight: 700; margin-bottom: 4px;
}
.pc-row {
  display: grid; grid-template-columns: 1fr auto auto auto; gap: 8px; align-items: center;
  width: 100%; text-align: left; padding: 5px 8px; border-radius: 6px;
  border: 1px solid transparent; transition: background 0.12s, border-color 0.12s;
}
.pc-row:hover { background: var(--panel-2); border-color: var(--line); }
.pc-row .pc-name { font-size: 11.5px; color: var(--txt-2); overflow-wrap: break-word; }
.pc-row.has-notes .pc-name { color: var(--txt); }
/* The row whose thread is open on the right. The bar on the leading edge is
   what carries it — a filled row would fight the notes it points at. */
.pc-row.on {
  background: var(--panel-2); border-color: var(--accent);
  box-shadow: inset 2px 0 0 var(--accent);
}
.pc-row.on .pc-name { color: var(--txt); font-weight: 600; }
.pc-count { font-family: var(--mono); font-size: 10px; color: var(--txt-3); min-width: 12px; text-align: right; }
.pc-drafts {
  font-family: var(--mono); font-size: 9px; font-weight: 700; padding: 1px 5px;
  border-radius: 4px; background: var(--track); color: var(--txt-3);
}
.pc-gone {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  padding: 1px 5px; border-radius: 4px; background: rgba(248, 113, 113, 0.16); color: var(--bad);
}

/* ------------------------------------------- the thread inside the pane */
/* The pane scrolls as one — header, notes, composer — rather than the notes
   scrolling inside a fixed frame. In a popup the frame was the screen and a
   capped stream was the only option; in a column it just meant two scrollbars
   inside one another. */
.pf-detail .pc-stream { display: grid; gap: 9px; margin-top: 12px; }
.pf-detail .cm-item .cm-meta { flex-wrap: wrap; }

/* ------------------------------------------------ replies, both popups */
/* Shared by the skill thread and the project thread — a conversation is a
   conversation, and the two boxes have no business looking different. The
   indent plus the rule down the left is what says "these answer the note
   above"; everything else stays a shade quieter than the parent so a long
   thread still reads top to bottom. */
.pc-replies { margin: 8px 0 0 4px; display: grid; gap: 6px; border-left: 2px solid var(--line-2); padding-left: 10px; }
.pc-reply .cm-meta { flex-wrap: wrap; gap: 5px; }
.pc-reply .cm-text { font-size: 12px; color: var(--txt-2); }
/* The badge carries the colour here rather than a border, because a reply is
   already inside a bordered, tinted comment and a second frame around it made
   the two-column layout look like a stack of boxes. */
.pc-reply .notif-scope { font-size: 8px; padding: 1px 5px; margin-top: 0; }
.pc-reply.admin .notif-scope { background: rgba(167, 139, 250, 0.18); color: var(--accent-2); }
.pc-reply.member .notif-scope { background: rgba(34, 211, 238, 0.16); color: var(--accent); }
.pc-replylink {
  margin-top: 7px; font-size: 11px; font-weight: 600; color: var(--txt-3);
  padding: 2px 0; transition: color 0.12s; text-align: left;
}
.pc-replylink:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.pc-replybox { margin-top: 8px; display: grid; gap: 6px; }
.pc-replybox textarea { min-height: 52px; font-size: 12px; }
.pc-replybtns { display: flex; gap: 6px; justify-content: flex-end; }

.pc-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.pc-tag {
  display: inline-flex; align-items: center; gap: 2px;
  border-radius: 99px; padding: 1px 3px 1px 8px; font-size: 10.5px; font-weight: 600;
  background: rgba(167, 139, 250, 0.14); color: var(--accent-2);
  border: 1px solid rgba(167, 139, 250, 0.34);
}
.pc-tag-go { color: inherit; font: inherit; }
.pc-tag-go:hover { text-decoration: underline; text-underline-offset: 2px; }
.pc-tag-x {
  width: 15px; height: 15px; border-radius: 99px; display: grid; place-items: center;
  font-size: 8px; color: inherit; opacity: 0.7;
}
.pc-tag-x:hover { background: rgba(248, 113, 113, 0.2); color: var(--bad); opacity: 1; }
.pc-tagpick { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 10px; }
.pc-tagpick select.field { max-width: 260px; }

/* -------------------------------------------- projects in master edit */
.me-projs { display: grid; gap: 10px; }
.me-proj { border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); overflow: hidden; }
.me-proj-head { display: grid; grid-template-columns: auto 1fr auto; gap: 11px; align-items: center; padding: 11px 13px; }
.me-proj-name { font-weight: 620; font-size: 13px; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.me-proj-members { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 13px 11px; }
.mem-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 99px; font-size: 11.5px; font-weight: 550;
  border: 1px solid var(--line); background: var(--panel); color: var(--txt-3);
  transition: background 0.13s, color 0.13s, border-color 0.13s;
}
.mem-chip .dot { width: 7px; height: 7px; border-radius: 99px; background: var(--tint); opacity: 0.45; }
.mem-chip:hover { color: var(--txt); border-color: var(--line-2); }
.mem-chip.on { color: var(--txt); border-color: color-mix(in srgb, var(--tint) 55%, transparent); background: color-mix(in srgb, var(--tint) 15%, transparent); }
.mem-chip.on .dot { opacity: 1; box-shadow: 0 0 8px var(--tint); }

.me-content { padding: 0 13px 12px; display: grid; gap: 3px; }
.me-content-row {
  display: grid; grid-template-columns: 96px minmax(120px, 1fr) 2fr auto auto;
  gap: 9px; align-items: center; padding: 3px 0; font-size: 11.5px;
}
.me-content-row .pc-name { color: var(--txt-2); overflow-wrap: anywhere; }
.me-content-row .help-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.me-content-row .del {
  width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center;
  font-size: 10px; color: var(--txt-3); border: 1px solid transparent;
}
.me-content-row .del:hover { color: var(--bad); border-color: rgba(248, 113, 113, 0.32); background: rgba(248, 113, 113, 0.1); }
.pc-bucket {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 700;
  color: var(--txt-3); white-space: nowrap;
}

/* the import picker */
.pick-list { display: grid; gap: 2px; max-height: 46vh; overflow: auto; padding-right: 4px; }
.pick-row {
  display: grid; grid-template-columns: auto auto 1fr auto auto; gap: 9px; align-items: center;
  padding: 6px 8px; border-radius: 7px; cursor: pointer; transition: background 0.12s;
}
.pick-row:hover { background: var(--panel-2); }
.pick-row.muted { opacity: 0.62; }
.pick-name { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-tag {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  padding: 2px 6px; border-radius: 5px; background: rgba(52, 211, 153, 0.16); color: var(--good); white-space: nowrap;
}
.pick-tag.muted { background: var(--track); color: var(--txt-3); }

/* ---------------------------------------------------------------- misc */
.empty-state { text-align: center; padding: 70px 20px; color: var(--txt-3); }
.empty-state .big { font-size: 34px; margin-bottom: 10px; opacity: 0.5; }
.legend-row { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; font-size: 11.5px; color: var(--txt-3); margin-top: 14px; }
.legend-row .k { display: inline-flex; align-items: center; gap: 6px; }
/* The one line off the old edit bar worth keeping: how to read the timeline.
   It sits at the far end so the rank scale still reads first. */
.legend-row .legend-note { margin-left: auto; color: var(--txt-3); opacity: 0.8; }

.help-note { font-size: 11.5px; color: var(--txt-3); line-height: 1.6; }
.kbd { font-family: var(--mono); font-size: 10.5px; padding: 1px 5px; border-radius: 4px; background: var(--track); border: 1px solid var(--line); }

@media (max-width: 780px) {
  .topbar { flex-wrap: wrap; padding: 10px 14px; }
  main { padding: 18px 14px 80px; }
  .cat-header { grid-template-columns: auto 1fr auto; gap: 10px; }
  .cat-header .cat-mini, .cat-header .cat-xp { display: none; }
  .stat-tiles { grid-template-columns: 1fr 1fr; }
  .me-sec-head { grid-template-columns: auto 1fr; }
  .me-skill { grid-template-columns: auto 1fr; }
  .proj-head { grid-template-columns: auto auto 1fr auto; }
  .proj-head .proj-meta { display: none; }
  .me-content-row { grid-template-columns: 1fr auto auto; }
  .me-content-row .pc-bucket, .me-content-row .help-note { display: none; }
}

@media print {
  body::before, .topbar, .btn { display: none !important; }
  .cat { break-inside: avoid; }
}

/* ------------------------------------------------------- work tracker */
/* A timesheet, laid out like the spreadsheet it replaces — one row a day,
   ruled into weeks. Familiarity is the point: the people filling this in have
   been filling in the same grid for a year. */

.wk-field { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--txt-3); }
.wk-field .field { width: 110px; }
.wk-field .field.wk-narrow { width: 62px; }
.wk-unit { font-size: 10.5px; color: var(--txt-3); }
.wk-readout { display: flex; align-items: baseline; gap: 7px; font-size: 11.5px; color: var(--txt-3); }
.wk-readout b { font-size: 13px; color: var(--txt); font-weight: 650; }

/* The four numbers worth knowing before reading a single row. */
.wk-summary {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; margin: 4px 0 16px;
}
.wk-stat {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel); padding: 11px 14px;
}
.wk-stat .v { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; color: var(--txt); }
.wk-stat .k { font-size: 10.5px; color: var(--txt-3); margin-top: 2px; }
/* Outstanding is the number the sheet exists to produce, so it is the one that
   carries colour — and it goes quiet the moment there is nothing owed. */
.wk-stat.owed { border-color: rgba(251, 146, 60, 0.4); background: rgba(251, 146, 60, 0.07); }
.wk-stat.owed .v { color: var(--warn); }
.wk-stat.paid .v { color: var(--good, #34d399); }

.wk-nav { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 10px; }
.wk-month { font-size: 14px; font-weight: 650; letter-spacing: -0.01em; min-width: 132px; text-align: center; }

.wk-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); }
.wk-table { width: 100%; border-collapse: collapse; min-width: 1010px; }
.wk-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel-2); border-bottom: 1px solid var(--line-2);
  font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  color: var(--txt-2); text-align: left; padding: 9px 8px; white-space: nowrap;
}
.wk-table td { padding: 3px 8px; border-bottom: 1px solid var(--line); font-size: 11.5px; vertical-align: middle; }
.wk-row:last-child td { border-bottom: none; }
/* The rule that opens a week is what makes the month scannable — it is doing
   the job the merged "Week 1" cell did in the sheet. */
.wk-row.wk-week-start td { border-top: 1px solid var(--line-2); }
.wk-row:hover td { background: var(--panel-2); }
.wk-weekend td { background: rgba(255, 255, 255, 0.022); }
/* The row that closes an invoice run. A line under it says "everything above
   here is settled" without needing a legend. */
.wk-closes td { border-bottom: 2px solid var(--accent-2); }

.wk-c-week { width: 62px; font-size: 10px; font-weight: 700; color: var(--txt-3); white-space: nowrap; }
.wk-c-day { width: 92px; white-space: nowrap; font-family: var(--mono); font-size: 11px; color: var(--txt-2); }
.wk-dow { display: inline-block; width: 28px; color: var(--txt-3); }
.wk-c-tick { width: 46px; text-align: center; }
.wk-c-hours { width: 74px; }
.wk-c-proj { width: 210px; }
.wk-c-notes { min-width: 200px; }
.wk-c-amt { width: 108px; text-align: right; font-family: var(--mono); font-size: 11px; color: var(--txt-2); white-space: nowrap; }
.wk-total { font-weight: 700; color: var(--txt); }

.wk-table .field.sm { width: 100%; font-size: 11.5px; padding: 3px 6px; }
.wk-hours { text-align: center; }
/* Overtime is worth seeing at a glance down the column — a day that ran long
   is the thing somebody scanning a month is looking for. */
.wk-has-extra { border-color: rgba(251, 146, 60, 0.5); color: var(--warn); font-weight: 650; }
.wk-extra-note { color: var(--warn); font-weight: 700; }
/* Spinners steal width in a 74px column and nobody nudges hours one arrow at
   a time anyway. */
.wk-hours::-webkit-outer-spin-button, .wk-hours::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.wk-hours { -moz-appearance: textfield; }

.wk-tick {
  width: 17px; height: 17px; border-radius: 4px; display: inline-grid; place-items: center;
  font-size: 10px; line-height: 1; border: 1px solid var(--line-2); background: var(--track);
  color: transparent; transition: background 0.12s, border-color 0.12s, color 0.12s;
}
button.wk-tick { cursor: pointer; }
button.wk-tick:hover { border-color: var(--txt-3); }
.wk-tick.on { background: var(--accent); border-color: var(--accent); color: var(--bg); }
span.wk-tick { opacity: 0.75; }

@media (max-width: 860px) {
  .wk-summary { grid-template-columns: repeat(2, 1fr); }
}
/* A settled run whose rows no longer add up to what was invoiced. The frozen
   figure stays put; the difference is called out beside it rather than
   silently folded in. */
.wk-drift { color: var(--warn); }
.wk-drift-note {
  display: block; font-size: 9px; font-weight: 700; letter-spacing: 0.03em;
  color: var(--warn); opacity: 0.9; white-space: nowrap;
}

/* Master Edit -> Money: whoever is paid in something other than the default.
   Exceptions are worth listing in one place; the rule is not. */
.money-list { display: grid; gap: 5px; margin-top: 12px; }
.money-row {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: center;
  width: 100%; text-align: left; padding: 6px 9px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--panel-2); transition: border-color 0.12s;
}
.money-row:hover { border-color: var(--accent); }
.money-name { font-size: 12px; color: var(--txt); font-weight: 600; }
.money-cur {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  padding: 2px 7px; border-radius: 5px; white-space: nowrap;
  background: rgba(52, 211, 153, 0.14); color: var(--good);
  border: 1px solid rgba(52, 211, 153, 0.32);
}
.money-rate { font-family: var(--mono); font-size: 10.5px; color: var(--txt-3); white-space: nowrap; }

/* The practical facts on a profile — versions somebody runs, what they cost.
   Looked up rather than remembered, so they belong on the card and not only
   inside the Edit dialog. */
.hero-facts {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line);
}
.hero-facts .fact {
  display: flex; align-items: baseline; gap: 6px;
  padding: 4px 10px; border-radius: 99px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.hero-facts .k { font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800; color: var(--txt-3); }
.hero-facts .v { font-family: var(--mono); font-size: 11.5px; color: var(--txt); font-weight: 650; }

/* A checkbox that carries its own explanation rather than just a label. */
.m-check { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start; cursor: pointer; }
.m-check input { margin-top: 3px; }
.m-check > span { display: grid; gap: 3px; font-size: 12.5px; color: var(--txt-2); }
.m-check .help-note { margin: 0; }

/* ------------------------------------------------- projects: tasks & general */
/* General Feedback is pinned above the project list rather than given a tab
   of its own — same conversation, same detail pane, and the tab bar is
   already carrying enough. */
.pf-general {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: center;
  width: 100%; text-align: left; padding: 9px 12px; margin-bottom: 8px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel); border-left: 3px solid var(--accent-2);
  transition: border-color 0.12s, background 0.12s;
}
.pf-general:hover { background: var(--panel-2); }
.pf-general.on { border-color: var(--accent-2); background: rgba(167, 139, 250, 0.08); }
.pf-general-i { font-size: 15px; }
.pf-general-t { display: grid; gap: 1px; font-size: 12.5px; font-weight: 600; color: var(--txt); min-width: 0; }
.pf-general-t .help-note { font-weight: 400; }
.notif-badge.sm { padding: 0 6px; font-size: 9px; }

.pf-none { padding: 18px 14px; font-size: 12px; color: var(--txt-3); display: grid; gap: 6px; }

/* A scene, then the stages of it. The indent is what says the stages belong
   to the file above them; nothing else needs to. */
.scene { border-top: 1px solid var(--line); padding-top: 2px; }
.scene:first-child { border-top: none; }
.scene-head { grid-template-columns: 1fr auto auto; }
.scene-head.on { background: var(--panel-2); box-shadow: inset 2px 0 0 var(--accent); }
.scene-pipe {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.09em; font-weight: 800;
  padding: 1px 6px; border-radius: 4px; white-space: nowrap;
  background: var(--track); color: var(--txt-3);
}

.task-list { display: grid; gap: 1px; margin: 0 0 6px 10px; padding-left: 9px; border-left: 2px solid var(--line-2); }
.task-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center;
  padding: 3px 7px; border-radius: 5px; transition: background 0.12s;
}
.task-row:hover { background: var(--panel-2); }
.task-row.on { background: var(--panel-2); box-shadow: inset 2px 0 0 var(--accent); }
/* Somebody else's stage is shown to an admin for context, so it stands back. */
.task-row:not(.mine) .task-name { color: var(--txt-3); }
.task-name {
  font-size: 11.5px; color: var(--txt-2); text-align: left;
  display: flex; align-items: center; gap: 5px; min-width: 0;
}
.task-name:hover { color: var(--accent); }
.task-row.done .task-name { color: var(--txt-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.task-who {
  width: 20px; height: 20px; border-radius: 6px; flex: none;
  display: grid; place-items: center; font-size: 8.5px; font-weight: 800;
  background: var(--track); color: var(--txt-3); border: 1px solid var(--line);
}

/* The strip under a stage heading in the detail pane: who has it, is it done. */
.pf-task-bar { display: flex; align-items: center; gap: 8px; margin-top: 9px; }
.pf-task-who { font-size: 11.5px; color: var(--txt-2); font-weight: 600; }
.pf-task-who.unassigned { color: var(--txt-3); font-weight: 400; font-style: italic; }

/* ---------------------------------------------------------- project admin */
.pa-modes { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin: 2px 0 14px; }
.pa-mode {
  padding: 6px 13px; border-radius: 8px; font-size: 12px; font-weight: 600;
  color: var(--txt-3); border: 1px solid var(--line); background: var(--panel);
  transition: background 0.13s, color 0.13s, border-color 0.13s;
}
.pa-mode:hover { color: var(--txt); background: var(--panel-2); }
.pa-mode.on { background: var(--txt); color: var(--bg); border-color: var(--txt); }

.pa-list { display: grid; gap: 10px; }
.pa-proj { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); overflow: hidden; }
.pa-proj.open { border-color: var(--line-2); }
.pa-proj-head { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; padding: 10px 12px; }
.pa-scenes { display: grid; gap: 2px; padding: 0 12px 12px; }

.pa-scene { border-top: 1px solid var(--line); padding-top: 8px; }
.pa-scene-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pa-scene-name { font-size: 12.5px; font-weight: 650; color: var(--txt); min-width: 0; }
/* Same width as the assign dropdowns below it, and the same trailing button
   width, so the scene's pipeline sits directly above the people doing it
   rather than floating off on its own. */
.pa-pipe { width: 172px; flex: none; margin-left: auto; }
.pa-scene-head > .del { width: 26px; flex: none; }

/* One row per stage: done, name, who has it, notes.

   Every row was its own grid, so `auto` columns sized themselves per row and
   nothing lined up down the scene — worse on the rows with nobody assigned,
   which have no notes button to fill the last column. The rows now share one
   set of tracks declared on the parent, with the row itself as `display:
   contents`, so a column is the same width on every line whatever is in it. */
.pa-tasks {
  display: grid; grid-template-columns: 17px minmax(0, 1fr) 172px 26px;
  gap: 3px 8px; align-items: center;
  margin: 7px 0 4px 4px; padding-left: 10px; border-left: 2px solid var(--line-2);
}
.pa-task { display: contents; }
/* `display: contents` leaves nothing to paint, so the hover lands on the cells. */
.pa-task:hover > * { background: var(--panel-2); }
.pa-note-btn { justify-self: center; }
.pa-task.open .pa-stage { color: var(--txt-3); }
.pa-task.done .pa-stage { color: var(--txt-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.pa-stage { font-size: 11.5px; color: var(--txt-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pa-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.pa-card { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); padding: 12px 14px; }
.pa-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.pa-card-name { font-size: 13px; font-weight: 650; color: var(--txt); }
.pa-card-proj { margin-top: 9px; }
.pa-card-proj-name {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  color: var(--txt-3); margin-bottom: 3px;
}
.pa-card-task {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 8px; align-items: center;
  padding: 3px 6px; border-radius: 5px; font-size: 11.5px;
}
.pa-card-task:hover { background: var(--panel-2); }
.pa-card-task.done .pa-card-scene { color: var(--txt-3); text-decoration: line-through; text-decoration-thickness: 1px; }
.pa-card-scene { color: var(--txt-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pa-card-stage { font-family: var(--mono); font-size: 9.5px; color: var(--txt-3); white-space: nowrap; }

.pa-stages { display: grid; gap: 18px; }
.pa-stage-group { display: grid; gap: 8px; }
.pa-stage-col { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); padding: 9px 12px; }
.pa-stage-col-head {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px;
  font-size: 11px; font-weight: 700; color: var(--txt-2);
}
.pa-stage-col-head .chip-pct { margin-left: auto; font-family: var(--mono); font-size: 9.5px; color: var(--txt-3); }

@media (max-width: 720px) {
  .pa-tasks { grid-template-columns: 17px minmax(0, 1fr) 26px; }
  .pa-task select { grid-column: 1 / -1; }
}

/* -------------------------------------------------------------- resources */
.res-pick { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 14px; }
.res-cat {
  padding: 6px 12px; border-radius: 99px; font-size: 11.5px; font-weight: 600;
  color: var(--txt-3); border: 1px solid var(--line); background: var(--panel);
  transition: background 0.13s, color 0.13s, border-color 0.13s;
}
.res-cat:hover { color: var(--txt); background: var(--panel-2); }
.res-cat.on { background: var(--accent); color: var(--bg); border-color: var(--accent); }

/* One card per stage. They sit side by side because a stage list is short and
   the whole pipeline should be readable without scrolling a column at a time. */
.res-stages { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; align-items: start; }
.res-stage {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel); padding: 12px 14px;
}
/* Everything ticked. Quiet, not a fanfare — it will be reset in a minute. */
.res-stage.complete { border-color: rgba(52, 211, 153, 0.4); background: rgba(52, 211, 153, 0.05); }
.res-stage-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.res-stage-name { font-size: 12px; font-weight: 700; letter-spacing: 0.02em; color: var(--txt); }
.res-count { font-family: var(--mono); font-size: 10px; color: var(--txt-3); }
.res-stage.complete .res-count { color: var(--good); }

.res-items { display: grid; gap: 1px; }
.res-sub {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  color: var(--txt-3); margin: 8px 0 3px;
}
.res-sub:first-child { margin-top: 0; }
.res-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: start;
  padding: 4px 6px; border-radius: 5px; font-size: 11.5px;
  color: var(--txt-2); line-height: 1.4; transition: background 0.12s;
}
.res-item:hover { background: var(--panel-2); }
.res-item.on { color: var(--txt-3); }
.res-item.on .res-text { text-decoration: line-through; text-decoration-thickness: 1px; }
.res-item .wk-tick { margin-top: 1px; }
.res-text { text-align: left; color: inherit; font: inherit; min-width: 0; overflow-wrap: anywhere; }
/* An item with an example behind it advertises it, and says so on hover. */
button.res-text.has-shot { cursor: pointer; }
button.res-text.has-shot:hover { color: var(--accent); }
.res-shot-flag { font-size: 9px; margin-left: 5px; opacity: 0.65; vertical-align: 1px; }
button.res-text.has-shot:hover .res-shot-flag { opacity: 1; }

/* Components of an item. The rule down the left is what says they belong to
   the line above; nothing else needs to. */
.res-kids {
  display: grid; gap: 1px; margin: 1px 0 3px 13px;
  padding-left: 9px; border-left: 2px solid var(--line-2);
}
.res-item.kid { font-size: 11px; padding: 3px 6px; }
.res-item.kid .wk-tick { width: 14px; height: 14px; font-size: 8px; }

/* The admin's way in. Invisible until the row is hovered, because on a list of
   twenty it would otherwise be twenty camera icons competing with the text. */
.res-cam {
  width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center;
  font-size: 10px; opacity: 0; color: var(--txt-3);
  transition: opacity 0.12s, background 0.12s, color 0.12s;
}
.res-item:hover .res-cam { opacity: 0.7; }
.res-cam:hover { opacity: 1; background: var(--panel); color: var(--accent); }
.res-cam.on { opacity: 0.9; color: var(--accent); }

/* The image dialog: what is on it now, and the two ways to change that. */
.cl-shot { display: grid; gap: 12px; }
.cl-shot-now {
  position: relative; display: grid; place-items: center; min-height: 150px;
  border: 1px dashed var(--line-2); border-radius: var(--r-sm);
  background: var(--panel-2); padding: 10px; overflow: hidden;
}
.cl-shot-now img { max-width: 100%; max-height: 300px; border-radius: 6px; display: block; }
.cl-shot-empty { font-size: 12px; color: var(--txt-3); font-style: italic; }
.cl-shot-tag {
  position: absolute; top: 8px; right: 8px;
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  padding: 2px 7px; border-radius: 99px;
  background: var(--track); color: var(--txt-3); border: 1px solid var(--line);
}
.cl-shot-tag.new { background: rgba(52, 211, 153, 0.16); color: var(--good); border-color: rgba(52, 211, 153, 0.4); }
.cl-shot-ways { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.res-edit { display: grid; gap: 8px; }
.res-edit textarea { font-family: var(--mono); font-size: 11.5px; line-height: 1.6; }
.res-edit-foot { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.res-edit-foot .help-note { max-width: 100%; }

.res-add { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.res-standards { display: grid; gap: 4px; }
.std-list { display: grid; gap: 6px; margin-bottom: 14px; }
.std { border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel); overflow: hidden; }
.std.open { border-color: var(--line-2); }
.std-head {
  display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center;
  width: 100%; text-align: left; padding: 10px 13px; transition: background 0.13s;
}
.std-head:hover { background: var(--panel-2); }
.std-head .chev { transition: transform 0.2s; }
.std-head .chev.down { transform: rotate(90deg); }
.std-title { font-size: 12.5px; font-weight: 600; color: var(--txt); }
.std-links-n { font-family: var(--mono); font-size: 9.5px; color: var(--txt-3); white-space: nowrap; }
.std-body { padding: 2px 13px 13px 34px; display: grid; gap: 10px; }
.std-text { font-size: 12.5px; color: var(--txt-2); line-height: 1.6; overflow-wrap: break-word; }
.std-links { display: flex; flex-wrap: wrap; gap: 6px; }
.std-link {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 99px; font-size: 11.5px; text-decoration: none;
  background: rgba(34, 211, 238, 0.12); color: var(--accent);
  border: 1px solid rgba(34, 211, 238, 0.3); transition: background 0.12s;
}
.std-link:hover { background: rgba(34, 211, 238, 0.22); }
.std-acts { display: flex; align-items: center; gap: 6px; border-top: 1px solid var(--line); padding-top: 10px; }

/* The post-import list of what was left out. Grouped by job, monospaced,
   because the useful thing about a rejected filename is its exact shape. */
.skip-group { margin-bottom: 12px; }
.skip-folder {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800;
  color: var(--txt-3); margin-bottom: 4px;
}
.skip-file {
  font-family: var(--mono); font-size: 11px; color: var(--txt-2);
  padding: 3px 9px; border-radius: 5px; background: var(--panel-2);
  border-left: 2px solid var(--warn); margin-bottom: 2px;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------- the connect gate */
/* The one ask that has to land, so it gets the middle of the screen once a
   session. Narrow and centred — a title, a sentence, one button — because
   anything more to read is something to skip. */
.modal.gate {
  max-width: 380px; text-align: center;
  padding: 30px 30px 24px; display: grid; gap: 0; justify-items: center;
}
.gate-mark {
  width: 56px; height: 56px; border-radius: 16px; display: grid; place-items: center;
  background: #0b1017; border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 0 26px rgba(34, 211, 238, 0.2); margin-bottom: 15px;
}
.gate-mark img { display: block; width: 40px; height: 40px; }
.modal.gate h3 { margin: 0 0 8px; font-size: 17px; letter-spacing: -0.02em; }
.gate-say { font-size: 12.5px; color: var(--txt-2); line-height: 1.6; margin-bottom: 20px; }
.gate-go { width: 100%; justify-content: center; padding: 11px 18px; font-size: 13.5px; }
.gate-skip {
  margin-top: 12px; font-size: 11.5px; color: var(--txt-3);
  padding: 4px 8px; border-radius: 6px; transition: color 0.12s;
}
.gate-skip:hover { color: var(--txt-2); text-decoration: underline; text-underline-offset: 2px; }
