/* Portask — global stylesheet
   Source of truth: docs/brandbook.md (client-approved, locked constants).
   Phase 1 scope: design tokens + auth-shell components only.
   Do NOT add topbar/waveform/task-card/rail styles here until those
   templates exist (Phase 2+) — see brandbook "Enforcement note". */

:root{
  --bg:#0B0D0F;
  --surface:#14171A;
  --surface-raised:#1B1F23;
  --border:#262B2F;
  --text:#ECEAE4;
  --text-secondary:#8B9096;
  --text-muted:#5B6167;
  --accent:#E8A33D;
  --accent-dim:#3A2E18;
  --open:#E2503D;
  --open-dim:#3A1E1A;
  --progress:#4F8FE8;
  --progress-dim:#182A3E;
  --resolved:#4FB286;
  --resolved-dim:#132C22;
}
*{box-sizing:border-box;}
body{margin:0;background:var(--bg);color:var(--text);font-family:'Space Grotesk',sans-serif;}
.mono{font-family:'JetBrains Mono',monospace;}

/* ---------------------------------------------------------------------
   Auth shell (Phase 1 extension — see docs/brandbook.md "Frontend
   extensions" section). Centered card layout for login/signup/dashboard,
   built from the same tokens/radius-scale/border rules as the mockup's
   components (8px card radius, 1px var(--border) hairlines,
   surface-raised for input/card backgrounds, accent + #1A1408 text for
   primary actions).
   --------------------------------------------------------------------- */

.auth-shell{
  min-height:100vh;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:24px;
}

.auth-card{
  width:100%;
  max-width:400px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:12px;
  padding:28px 26px;
}

.auth-title{
  font-size:19px;
  font-weight:500;
  margin:0 0 18px;
  color:var(--text);
}

/* ---------------------------------------------------------------------
   Brand mark (Phase 5 whitelabel extension — partials/brand_mark.html).
   Reproduces docs/brandbook.md's Topbar brand-mark spec exactly
   (22x22px, border-radius:5px, solid --accent fill) even though no real
   .topbar exists yet — see that partial's own docstring. Placed above
   .auth-card on today's centered-card pages as a forward-compatible
   stand-in; drop-in compatible with the real topbar once Phase 2's
   three-column shell lands.
   --------------------------------------------------------------------- */
.brand-row{
  display:flex;
  align-items:center;
  gap:8px;
  margin-bottom:14px;
}
.brand-mark{
  width:22px;
  height:22px;
  border-radius:5px;
  background:var(--accent);
  display:flex;
  align-items:center;
  justify-content:center;
  font-weight:700;
  font-size:13px;
  line-height:1;
  flex-shrink:0;
}
.brand-mark--logo{
  object-fit:cover;
  background:var(--surface-raised); /* visible while a slow/broken logo loads */
}
.brand-name{
  font-size:13px;
  font-weight:500;
  color:var(--text-secondary);
}

.auth-form{
  display:flex;
  flex-direction:column;
  gap:14px;
}

.field{
  display:flex;
  flex-direction:column;
  gap:6px;
}

.field-label{
  font-size:12px;
  color:var(--text-secondary);
}

.field input{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  color:var(--text);
  font-family:'Space Grotesk',sans-serif;
  font-size:14px;
  padding:9px 11px;
}

.field input::placeholder{
  color:var(--text-muted);
}

.field input:focus{
  outline:none;
  border-color:var(--accent);
}

.btn-primary{
  background:var(--accent);
  color:#1A1408;
  border:none;
  border-radius:8px;
  font-family:'Space Grotesk',sans-serif;
  font-size:14px;
  font-weight:500;
  padding:10px 14px;
  cursor:pointer;
  margin-top:4px;
}

.btn-primary:hover{
  filter:brightness(1.05);
}

.auth-error{
  background:var(--open-dim);
  color:var(--open);
  font-size:13px;
  border-radius:8px;
  padding:9px 11px;
  margin:0 0 16px;
}

.auth-meta{
  color:var(--text-secondary);
  font-size:13px;
  margin:18px 0 0;
}

.auth-meta a{
  color:var(--accent);
  text-decoration:none;
}

.auth-meta a:hover{
  text-decoration:underline;
}

/* Dashboard (Phase 1 exit-criteria "resolved workspace context" page —
   simple key/value + list layout, not the real Phase 2 dashboard) */

.dash-meta{
  color:var(--text-secondary);
  font-size:13px;
  margin:0 0 20px;
}

.dash-meta strong{
  color:var(--text);
  font-weight:500;
}

.dash-section{
  color:var(--text);
  font-size:14px;
  margin:0 0 12px;
}

.dash-section strong{
  font-weight:500;
}

.dash-subtitle{
  font-size:12px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  margin:20px 0 8px;
}

.dash-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:2px;
}

.dash-list li{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:8px 10px;
  font-size:13px;
  color:var(--text-secondary);
}

.dash-list li a{
  color:var(--text);
  text-decoration:none;
  display:block;
}

.dash-list li a:hover{
  color:var(--accent);
}

.dash-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  margin:20px 0 8px;
}

.btn-small{
  display:inline-block;
  padding:6px 12px;
  font-size:12px;
  margin-top:0;
  text-decoration:none;
}

/* -----------------------------------------------------------------------
   Producer shell — project list/detail + client-invite UI (Phase 2,
   Track A). Reuses the auth-shell/auth-card centered-card pattern (per
   task brief: simple list/form pages, not the full 3-column mockup
   layout yet) and existing dash-* / field / btn-* primitives rather than
   introducing new visual idioms.
   ----------------------------------------------------------------------- */

.auth-card--wide{
  max-width:560px;
}

.project-list{
  list-style:none;
  margin:0 0 4px;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:6px;
}

.project-list li a{
  display:flex;
  align-items:center;
  justify-content:space-between;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:10px 12px;
  font-size:13.5px;
  color:var(--text);
  text-decoration:none;
}

.project-list li a:hover{
  border-color:var(--text-muted);
}

.project-list .project-list-meta{
  font-family:'JetBrains Mono',monospace;
  font-size:11px;
  color:var(--text-muted);
}

.invite-success{
  background:var(--resolved-dim);
  color:var(--resolved);
  font-size:13px;
  border-radius:8px;
  padding:10px 12px;
  margin:0 0 16px;
}

.invite-link-row{
  display:flex;
  align-items:center;
  gap:8px;
  margin-top:8px;
}

.invite-link-row input{
  flex:1;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:8px;
  color:var(--text);
  font-family:'JetBrains Mono',monospace;
  font-size:12px;
  padding:8px 10px;
}

.invite-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:6px;
}

.invite-list li{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 11px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}

.invite-email{
  font-size:13px;
  color:var(--text);
}

.invite-status{
  font-size:10px;
  font-weight:500;
  padding:2px 8px;
  border-radius:10px;
  font-family:'JetBrains Mono',monospace;
}

.invite-status.pending{
  background:var(--progress-dim);
  color:var(--progress);
}

.invite-status.accepted{
  background:var(--resolved-dim);
  color:var(--resolved);
}

.empty-state{
  color:var(--text-muted);
  font-size:13px;
  margin:0 0 8px;
}

/* -----------------------------------------------------------------------
   Invite card restyle (Phase 6b — frontend-brand-guardian, 2026-07-21).
   Per downloads/mockups/portask-invite-ui.html's `.invite-form`/
   `.invite-row`/`.invite-status` classes. Kept as a SINGLE-email form
   (one `.invite-email-input` + one `.send-btn`), not the mockup's
   multi-email chip-input — see templates/projects/detail.html's own
   comment for the full scope reasoning. New reusable pattern documented
   in docs/brandbook.md's Phase 6b section.
   ----------------------------------------------------------------------- */

.invite-card{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:10px;
  padding:16px 18px;
  margin-bottom:22px;
  max-width:560px;
}

.invite-card-title{
  font-size:15px;
  font-weight:500;
  color:var(--text);
  margin-bottom:4px;
}

.invite-card-sub{
  font-size:12.5px;
  color:var(--text-muted);
  margin:0 0 16px;
}

.invite-form{
  display:flex;
  flex-direction:column;
  gap:6px;
}

.invite-email-input{
  width:100%;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 12px;
  color:var(--text);
  font-size:13px;
  font-family:'Space Grotesk',sans-serif;
  margin-bottom:8px;
}

.invite-email-input::placeholder{
  color:var(--text-muted);
}

.invite-email-input:focus{
  outline:none;
  border-color:var(--accent);
}

.invite-send-row{
  display:flex;
  justify-content:flex-end;
}

.send-btn{
  padding:9px 18px;
  border-radius:8px;
  background:var(--accent);
  color:#1A1408;
  font-weight:500;
  font-size:13px;
  border:none;
  cursor:pointer;
  font-family:'Space Grotesk',sans-serif;
}

.send-btn:hover{
  filter:brightness(1.05);
}

.list-title{
  font-size:11px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  margin:0 0 10px;
  max-width:560px;
}

.invite-status-list{
  max-width:560px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:10px;
  overflow:hidden;
}

.invite-status-list .empty-state{
  padding:12px;
  margin:0;
}

.invite-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:10px 14px;
  border-bottom:1px solid var(--border);
}

.invite-row:last-child{
  border-bottom:none;
}

.invite-row .invite-email{
  font-size:13px;
  color:var(--text);
}

.invite-row .invite-project{
  font-size:11px;
  color:var(--text-muted);
  margin-top:2px;
}

.invite-row .invite-status{
  font-size:10.5px;
  padding:3px 10px;
  border-radius:10px;
  font-weight:500;
}

.invite-row .invite-status.pending{
  background:var(--accent-dim);
  color:var(--accent);
}

.invite-row .invite-status.accepted{
  background:var(--resolved-dim);
  color:var(--resolved);
}

/* -----------------------------------------------------------------------
   Workspace switcher (Phase 2, Track B — client shell). Persistent
   sidebar component listing a client's non-whitelabel producer
   workspaces/projects, GoHighLevel-style (not a Slack-style gate
   screen). Follows the brandbook's left-rail track-item pattern: same
   uppercase/muted/tracked rail-title treatment as `.dash-subtitle` /
   the mockup's `.rail-title`, and the same raised-surface (not
   accent-colored) active-state convention as track items. MUST only be
   rendered when g.tenant_mode == "main" — see the guard note in
   templates/partials/workspace_switcher.html.
   ----------------------------------------------------------------------- */

/* Restyled (nav-shell rebuild, 2026-07-21) to visually match
   downloads/mockups/portask-nav-shell.html's `.switcher`/
   `.switcher-item`/`.switcher-dot` classes EXACTLY (bordered
   raised-surface box, uppercase muted label, colored dot per entry) —
   per the task brief's explicit instruction to restyle this existing
   component's CSS rather than rebuild templates/partials/
   workspace_switcher.html's markup. Class names themselves are kept as
   `.ws-switcher*` (the partial's own pre-existing names) since the
   brief says match visually, not necessarily rename — renaming would
   have meant touching the partial's markup too, which was explicitly
   out of scope. */
.ws-switcher{
  border:1px solid var(--border);
  border-radius:8px;
  background:var(--surface-raised);
  padding:8px;
}

.ws-switcher-title{
  font-size:10px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  padding:2px 4px 6px;
  margin:0;
}

.ws-switcher-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:1px;
}

/* Colored "dot" per switcher entry, matching the mockup's
   `.switcher-dot` (7px circle) exactly — since each entry here is a
   Project (not a hand-picked skin), the dot color is derived
   deterministically from the project id so it's stable across page
   loads without needing a new stored-color column. */
.ws-switcher-item{
  display:flex;
  align-items:center;
  gap:8px;
  padding:7px 6px;
  border-radius:6px;
  text-decoration:none;
  color:var(--text-secondary);
  font-size:13px;
}

.ws-switcher-item::before{
  content:"";
  width:7px;
  height:7px;
  border-radius:50%;
  flex-shrink:0;
  background:var(--text-muted);
}

.ws-switcher-item:hover{
  background:var(--surface);
}

/* Active state: raised-surface + full-brightness text, NOT accent —
   accent stays reserved for the A/B toggle and skin identity per the
   brandbook's interaction-convention rule. */
.ws-switcher-item.active{
  background:var(--surface);
  color:var(--text);
}

.ws-switcher-item.active::before{
  background:var(--accent);
}

.ws-switcher-workspace{
  font-size:13px;
  font-weight:500;
}

.ws-switcher-item.active .ws-switcher-workspace{
  color:var(--text);
}

.ws-switcher-project{
  font-size:11.5px;
  color:var(--text-muted);
}

.ws-switcher-empty{
  color:var(--text-muted);
  font-size:12.5px;
  margin:0;
}

.btn-secondary{
  background:transparent;
  color:var(--text-secondary);
  border:1px solid var(--border);
  border-radius:8px;
  font-family:'Space Grotesk',sans-serif;
  font-size:13px;
  padding:8px 14px;
  cursor:pointer;
  margin-top:20px;
}

.btn-secondary:hover{
  color:var(--text);
  border-color:var(--text-muted);
}

/* -----------------------------------------------------------------------
   Producer delivery flow — song/version-grouping display + upload form
   (Phase 3, "producer side" track). Follows the same card/list
   primitives as the invite list above rather than introducing new
   visual idioms; version children are simply indented under their
   root within the same raised-surface card.
   ----------------------------------------------------------------------- */

.song-delivery-list{
  display:flex;
  flex-direction:column;
  gap:10px;
  margin:0 0 8px;
}

.song-delivery-card{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:12px 14px;
}

.song-delivery-header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  margin:0 0 10px;
}

.song-delivery-name{
  font-size:14px;
  font-weight:500;
  color:var(--text);
}

.song-delivery-count{
  font-family:'JetBrains Mono',monospace;
  font-size:11px;
  color:var(--text-muted);
}

.version-group-list{
  list-style:none;
  margin:0 0 12px;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:8px;
}

.version-group{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:8px;
  padding:8px 10px;
}

.version-root{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:13px;
  color:var(--text);
}

.version-children{
  list-style:none;
  margin:6px 0 0;
  padding:0 0 0 16px;
  border-left:1px solid var(--border);
  display:flex;
  flex-direction:column;
  gap:5px;
}

.version-child{
  display:flex;
  align-items:center;
  gap:8px;
  font-size:12.5px;
  color:var(--text-secondary);
}

.version-filename{
  word-break:break-all;
}

.version-tag{
  font-family:'JetBrains Mono',monospace;
  font-size:10px;
  color:var(--text-muted);
  background:var(--surface-raised);
  border-radius:10px;
  padding:2px 8px;
  white-space:nowrap;
}

.version-tag.original{
  color:var(--accent);
  background:var(--accent-dim);
}

.delivery-upload-form{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  gap:10px;
}

.delivery-upload-form .field{
  flex:1;
  min-width:160px;
}

.delivery-upload-form select{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  color:var(--text);
  font-family:'Space Grotesk',sans-serif;
  font-size:13px;
  padding:8px 10px;
}

.delivery-upload-form .btn-secondary{
  margin-top:0;
}

/* -----------------------------------------------------------------------
   Client raw-upload flow (Phase 3, client-raw-upload track; RESTYLED
   2026-07-21 per downloads/mockups/portask-upload-flow.html —
   frontend-brand-guardian visual-restyle pass, see brandbook's "Client
   upload flow — card picker + dropzone" section for the full writeup).
   `.category-picker`/`.category-option` (plain radio list) is fully
   retired here — replaced by `.cat-row`/`.cat-card` below, the mockup's
   3-card picker. `.field input[type="file"]` stays: still used by the
   producer delivery-upload form in detail.html (a plain file input
   there, out of scope for this pass) — do not remove.
   ----------------------------------------------------------------------- */

.field input[type="file"]{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  color:var(--text-secondary);
  font-family:'Space Grotesk',sans-serif;
  font-size:13px;
  padding:9px 11px;
}

/* Category card-picker (Mix / Master / Both) — mockup's `.cat-row`/
   `.cat-card`. "Both" is informational-only (see the template's own
   comment + brandbook section) — it never gets `.active` and never
   sets the hidden radio, so it cannot silently submit a fake category. */
.cat-row{
  display:flex;
  gap:10px;
  margin-bottom:4px;
}

.cat-card{
  flex:1;
  border:1px solid var(--border);
  border-radius:8px;
  padding:16px 14px;
  cursor:pointer;
  text-align:center;
  background:var(--surface-raised);
}

.cat-card.active{
  border-color:var(--accent);
  background:var(--accent-dim);
}

.cat-card--info{
  cursor:default;
}

.cat-title{
  font-size:13px;
  font-weight:500;
  color:var(--text);
  margin-bottom:4px;
}

.cat-sub{
  font-size:11px;
  color:var(--text-muted);
}

.cat-card.active .cat-sub{
  color:var(--accent);
}

.cat-both-note{
  font-size:12px;
  color:var(--text-secondary);
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 11px;
  margin:2px 0 0;
  display:none;
  line-height:1.5;
}

.cat-both-note.visible{
  display:block;
}

/* Dropzone — real drag-and-drop target wrapping the actual file input
   (input stays in the DOM, visually hidden, so it remains the single
   source of truth submitted with the form; see template JS). */
.dropzone{
  border:1px dashed var(--border);
  border-radius:8px;
  padding:28px;
  text-align:center;
  color:var(--text-muted);
  font-size:13px;
  cursor:pointer;
  position:relative;
}

.dropzone:hover{
  border-color:var(--text-muted);
}

.dropzone.dropzone--active{
  border-color:var(--accent);
  background:var(--accent-dim);
  color:var(--text);
}

.dropzone-sub{
  font-size:11px;
  margin-top:4px;
  color:var(--text-muted);
}

.dropzone input[type="file"]{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  opacity:0;
  cursor:pointer;
}

/* Selected-file list — static filenames + sizes only (no progress
   bars/percentages; see brandbook's explicit note on why the mockup's
   fake real-time progress UI was not reproduced). */
.file-list{
  display:flex;
  flex-direction:column;
  gap:8px;
}

.file-row{
  display:flex;
  align-items:center;
  gap:10px;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 12px;
}

.file-row .file-name{
  flex:1;
  font-size:12.5px;
  color:var(--text);
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.file-row .file-size{
  font-size:11px;
  color:var(--text-muted);
}

.upload-actions{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap:12px;
  margin-top:4px;
}

.upload-actions .btn-primary{
  margin-top:0;
}

.add-more-note{
  font-size:12px;
  color:var(--text-muted);
}

.song-group{
  margin:0 0 16px;
}

.song-group-title{
  font-size:13.5px;
  font-weight:500;
  color:var(--text);
  margin:0 0 6px;
}

.upload-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:6px;
}

.upload-list li{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 11px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
}

.upload-filename{
  font-size:13px;
  color:var(--text);
  flex:1;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.upload-category{
  font-size:10px;
  font-weight:500;
  padding:2px 8px;
  border-radius:10px;
  font-family:'JetBrains Mono',monospace;
  text-transform:uppercase;
}

.upload-category.mix{
  background:var(--progress-dim);
  color:var(--progress);
}

.upload-category.master{
  background:var(--accent-dim);
  color:var(--accent);
}

.upload-status{
  font-size:11px;
  color:var(--text-muted);
  font-family:'JetBrains Mono',monospace;
}

/* -----------------------------------------------------------------------
   Waveform + audio player component (Phase 4, Part 7 — "Playback &
   waveform engine"). Reproduces the brandbook's "Waveform panel"
   anatomy exactly: --surface container, 1px var(--border), 10px
   radius, 18px 18px 28px padding, two-layer canvas bar rendering
   (base gray #3A3E42 + accent overlay at globalAlpha 0.35, drawn by
   templates/partials/waveform_player.html's inline script). Play
   button + mono time readout follow the existing btn-secondary /
   .mono conventions rather than inventing a new control idiom.
   Instantiable multiple times per page — see the partial's docstring.
   ----------------------------------------------------------------------- */

.waveform-player{
  margin:10px 0 0;
}

.waveform-wrap{
  position:relative;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:10px;
  padding:18px 18px 28px;
  cursor:pointer;
}

.waveform-canvas{
  display:block;
  width:100%;
  height:120px;
}

/* Live seek/scrub playhead — a position indicator only, NOT the
   task/comment pin UI (separate, pin-colored, numbered-dot component
   built by a different track later). Reuses the pin's 2px-wide line
   treatment from the brandbook but in --text (neutral), since this is
   playback position, not a status-colored task marker. */
.wfp-playhead{
  position:absolute;
  top:18px;
  width:2px;
  height:120px;
  background:var(--text);
  opacity:0.6;
  pointer-events:none;
  left:0%;
}

.wfp-controls{
  display:flex;
  align-items:center;
  gap:10px;
  margin-top:10px;
}

.wfp-playbtn{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  color:var(--text);
  width:32px;
  height:32px;
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  font-size:11px;
  line-height:1;
  padding:0;
}

.wfp-playbtn:hover{
  border-color:var(--text-muted);
}

.wfp-time{
  font-size:12px;
  color:var(--text-muted);
}

.wfp-unavailable{
  color:var(--text-muted);
  font-size:13px;
  margin:10px 0 0;
}

/* -----------------------------------------------------------------------
   A/B toggle panel (Phase 4 — "A/B toggle wiring to real version
   pairs"). `.abtoggle` reproduces docs/brandbook.md's "A/B toggle"
   component-anatomy spec EXACTLY: pill container --surface-raised bg,
   1px border, border-radius 20px, 3px padding; buttons transparent/no
   border by default, JetBrains Mono 12px; active state solid --accent
   bg + #1A1408 text, font-weight 500. Reused verbatim as the
   segmented-control shape (per the brandbook's own instruction not to
   invent a different toggle style for future binary choices).
   `.abtoggle-panel`/`-header`/`-warning`/`-live-label` are new
   supporting chrome around that pill, following the nearest existing
   analogs (song-delivery-card surface treatment, .auth-error tone for
   the mismatch warning) rather than inventing new visual idioms.
   ----------------------------------------------------------------------- */

.abtoggle-panel{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:10px;
  padding:14px 16px;
  margin:10px 0 0;
}

.abtoggle-header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:18px;
  flex-wrap:wrap;
}

.abtoggle-title{
  font-size:12px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
}

.abtoggle{
  display:flex;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:20px;
  padding:3px;
  gap:2px;
}

.abtoggle-btn{
  border:none;
  background:transparent;
  color:var(--text-secondary);
  font-family:'JetBrains Mono',monospace;
  font-size:12px;
  padding:6px 14px;
  border-radius:16px;
  cursor:pointer;
  max-width:220px;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

.abtoggle-btn.active{
  background:var(--accent);
  color:#1A1408;
  font-weight:500;
}

.abtoggle-warning{
  color:var(--accent);
  background:var(--accent-dim);
  font-size:12px;
  border-radius:8px;
  padding:8px 10px;
  margin:10px 0 0;
}

.abtoggle-live-label{
  font-size:11px;
  color:var(--text-muted);
}

.abtoggle-audio{
  display:none;
}

/* -----------------------------------------------------------------------
   Persistent two-column nav shell (templates/app_shell.html) —
   REBUILD, 2026-07-21, replacing the previous three-column
   tracks-only shell per the priority fix ("current UI looks terrible,
   not professional"). Reproduces
   downloads/mockups/portask-nav-shell.html's `.app`/`.topbar`/`.body`/
   `.sidebar`/`.nav-section`/`.nav-item`/`.main` markup EXACTLY
   (grid-template-columns: 220px 1fr; outer 12px-radius
   hairline-bordered container; topbar 14px 20px padding — all
   unchanged constants from the brandbook's existing "Layout
   structure"/"Component anatomy" sections, just recomposed into the
   new grid/sidebar shape). See docs/brandbook.md's nav-shell-rebuild
   extension section for the full reasoning on why this replaced the
   old 190px/1fr/260px three-column grid rather than living alongside
   it.
   ----------------------------------------------------------------------- */

.app-shell-outer{
  padding:24px;
}

.app{
  width:100%;
  border:1px solid var(--border);
  border-radius:12px;
  overflow:hidden;
  background:var(--bg);
}

.topbar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:14px 20px;
  border-bottom:1px solid var(--border);
  background:var(--surface);
}

/* .brand / .brand-mark / .brand-name already defined above
   (Phase 5 brand_mark.html partial) — reused verbatim in the topbar
   per that partial's own "drops into the real topbar unchanged" note.
   Only the row wrapper class differs here (.brand, not .brand-row)
   because the topbar also needs the breadcrumb separator + project
   name inline in the same flex row, matching the mockup's `.brand`
   container exactly. */
.brand{
  display:flex;
  align-items:center;
  gap:10px;
}

.brand-sep{
  color:var(--text-muted);
  font-size:13px;
  margin:0 2px;
}

.project-name{
  color:var(--text-secondary);
  font-size:13px;
}

.topbar-right{
  display:flex;
  align-items:center;
  gap:14px;
}

/* `?` help icon-button + avatar circle — the mockup's fixed,
   non-overridable topbar-right pair (see app_shell.html's own
   docstring: "no more, no less"). Static/non-interactive this pass per
   the task brief — no interactive help-center behavior was asked for. */
.icon-btn{
  width:28px;
  height:28px;
  border-radius:6px;
  background:transparent;
  border:1px solid var(--border);
  color:var(--text-secondary);
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:13px;
  cursor:default;
}

.avatar{
  width:28px;
  height:28px;
  border-radius:50%;
  background:var(--surface-raised);
  border:1px solid var(--border);
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:11px;
  font-weight:500;
  color:var(--text-secondary);
  text-transform:uppercase;
}

.body{
  display:grid;
  grid-template-columns:220px 1fr;
  min-height:440px;
}

.sidebar{
  background:var(--surface);
  border-right:1px solid var(--border);
  padding:16px 12px;
  display:flex;
  flex-direction:column;
  gap:18px;
}

.rail-title{
  font-size:11px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  margin:0 0 8px 4px;
}

/* Persistent sidebar nav items (Workspace/Studio sections for a
   producer; switcher + per-project section for a client) — replaces
   the old shell's `.track-item` as the sidebar's primary interactive
   element. `.track-item` itself is kept below (now used for the
   horizontal track-chip strip inside detail.html's main column, not
   the sidebar) rather than deleted, since it's still a real,
   referenced class. */
.nav-item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:8px 10px;
  border-radius:8px;
  font-size:13px;
  color:var(--text-secondary);
  margin-bottom:2px;
  text-decoration:none;
  cursor:pointer;
}

.nav-item:hover:not(.active):not(.nav-item--disabled){
  color:var(--text);
}

.nav-item.active{
  background:var(--surface-raised);
  color:var(--text);
}

/* Billing — deliberately deferred product decision (Phase 7), not an
   oversight. Rendered as a non-link `<span>` (see
   templates/partials/nav_producer.html), visually grayed out and
   inert — no click handler, no route, per the task brief's explicit
   "visibly disabled/grayed out" requirement. */
.nav-item--disabled{
  color:var(--text-muted);
  cursor:not-allowed;
  opacity:0.6;
}

.nav-badge{
  font-size:10px;
  background:var(--accent-dim);
  color:var(--accent);
  border-radius:10px;
  padding:1px 7px;
  font-family:'JetBrains Mono',monospace;
}

.main{
  padding:20px 22px;
  display:flex;
  flex-direction:column;
  min-width:0;
}

/* Horizontal track-chip strip — detail.html's replacement for the old
   shell's dedicated left tracks-column, now that the sidebar is
   persistent nav rather than a per-project tracks list (see
   templates/projects/detail.html's own docstring for the full
   reasoning). Same track-item color/active-state convention as
   before (raised-surface + full-brightness text on active, never
   accent-colored — per the brandbook's own interaction-convention
   rule), just laid out as a row of pill-chips instead of a vertical
   column, since it no longer owns a dedicated 190px column. */
.track-chip-row{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
  margin-bottom:18px;
}

.track-chip{
  padding:6px 12px;
  border-radius:8px;
  font-size:13px;
  color:var(--text-secondary);
  text-decoration:none;
  background:var(--surface);
  border:1px solid var(--border);
}

.track-chip.active{
  background:var(--surface-raised);
  color:var(--text);
  border-color:var(--surface-raised);
}

.track-chip:hover:not(.active){
  color:var(--text);
}

/* Legacy track-item class — still referenced (see comment above
   .nav-item) but no longer rendered in the sidebar; kept for any
   future per-list use following the same visual convention. */
.track-item{
  padding:8px 10px;
  border-radius:8px;
  font-size:13px;
  color:var(--text-secondary);
  margin-bottom:2px;
  cursor:pointer;
  text-decoration:none;
  display:block;
}

.track-item.active{
  background:var(--surface-raised);
  color:var(--text);
}

.track-item:hover:not(.active){
  color:var(--text);
}

.track-header{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  margin-bottom:16px;
  gap:12px;
  flex-wrap:wrap;
}

.track-title{
  font-size:17px;
  font-weight:500;
  color:var(--text);
}

.track-meta{
  font-size:12px;
  color:var(--text-muted);
}

.legend{
  display:flex;
  gap:16px;
  margin-top:14px;
  font-size:12px;
  color:var(--text-secondary);
}

.legend span{
  display:inline-flex;
  align-items:center;
  gap:6px;
}

.legend i{
  width:8px;
  height:8px;
  border-radius:50%;
  display:inline-block;
}

/* .tasks-inline — replaces the old shell's dedicated right `.tasks-rail`
   column (that third column no longer exists in the new 2-column grid,
   per downloads/mockups/portask-nav-shell.html having no third
   column). Same `.tasks-title`/`.task-card` visual spec as before,
   just rendered inline in the main column below the waveform/legend
   instead of in its own persistent sidebar — see
   templates/projects/detail.html. */
.tasks-inline{
  margin-top:24px;
  padding-top:20px;
  border-top:1px solid var(--border);
}

.tasks-title{
  font-size:11px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  margin:0 0 12px 2px;
  display:flex;
  justify-content:space-between;
}

.task-card{
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:10px 12px;
  margin-bottom:10px;
}

.task-top{
  display:flex;
  justify-content:space-between;
  align-items:center;
  margin-bottom:6px;
  gap:8px;
}

.task-time{
  font-size:11px;
  color:var(--text-muted);
}

.task-status{
  font-size:10px;
  padding:2px 8px;
  border-radius:10px;
  font-weight:500;
  white-space:nowrap;
}

.task-status.open{
  background:var(--open-dim);
  color:var(--open);
}

.task-status.progress{
  background:var(--progress-dim);
  color:var(--progress);
}

.task-status.resolved{
  background:var(--resolved-dim);
  color:var(--resolved);
}

.task-text{
  font-size:12.5px;
  color:var(--text);
  line-height:1.4;
  margin-bottom:4px;
}

.task-client{
  font-size:11px;
  color:var(--text-muted);
}

/* .skins / .skin-dot / .skin-* — topbar skin picker, per brandbook's
   "White-label skin system" section. Not yet wired to real
   per-skin-switching logic (that's an open decision in the brandbook,
   flagged as unresolved — "confirm with user before building the
   skin-switching logic"); these classes exist so a page CAN render
   the picker visually (e.g. showing the workspace's current accent as
   the active dot) without inventing switching behavior. */
.skins{
  display:flex;
  align-items:center;
  gap:6px;
}

.skin-label{
  font-size:11px;
  color:var(--text-muted);
  margin-right:4px;
}

.skin-dot{
  width:16px;
  height:16px;
  border-radius:50%;
  cursor:pointer;
  border:2px solid transparent;
  display:inline-block;
}

.skin-dot.active{
  border-color:var(--text);
}

/* Inline task-stub note (used when a page renders the `.tasks-inline`
   shell without real task cards yet, per this pass's task brief
   allowing an honest stub). */
.tasks-inline .empty-state{
  margin:0;
}

/* -----------------------------------------------------------------------
   Nav-shell content helpers — generic content-area classes used by
   pages now living inside the main column of the new persistent shell
   (dashboard, project list, and the two nav-stub pages). Not
   component-specific like `.tasks-inline`/`.track-chip` above; these
   are just spacing/typography wrappers so plain content reads
   correctly at the new shell's `.main` padding instead of the old
   `.auth-card` padding.
   ----------------------------------------------------------------------- */
.dash-content{
  max-width:640px;
}

.stub-page{
  max-width:560px;
}

.stub-title{
  font-size:19px;
  font-weight:500;
  color:var(--text);
  margin:0 0 8px;
}

.stub-lede{
  font-size:13px;
  color:var(--text-secondary);
  line-height:1.5;
  margin:0;
}

.stub-list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:2px;
}

.stub-list li a{
  display:block;
  padding:8px 10px;
  border-radius:8px;
  background:var(--surface-raised);
  border:1px solid var(--border);
  color:var(--text-secondary);
  text-decoration:none;
  font-size:13px;
  margin-bottom:4px;
}

.stub-list li a:hover{
  color:var(--text);
}

/* -----------------------------------------------------------------------
   Unified whitelabel settings page (Phase 6b — frontend-brand-guardian,
   2026-07-21). Per downloads/mockups/portask-whitelabel-settings.html:
   a two-column `main` layout (settings sections + a client-facing
   preview panel), rendered inside app_shell.html's existing `.main`
   column (which already sits to the right of the persistent `.sidebar`
   — the mockup's own 220px sidebar + settings + preview 3-way split is
   therefore reproduced as sidebar (already exists) + this 2-col grid,
   not a 3rd grid level). New reusable "settings card" + "preview panel"
   pattern — documented in docs/brandbook.md's Phase 6b section.
   ----------------------------------------------------------------------- */

.settings-grid{
  display:grid;
  grid-template-columns:1fr 300px;
  gap:28px;
  align-items:start;
}

.settings-section{
  margin-bottom:26px;
}

.settings-section-title{
  font-size:14px;
  font-weight:500;
  color:var(--text);
  margin-bottom:4px;
}

.settings-section-sub{
  font-size:12px;
  color:var(--text-muted);
  margin-bottom:12px;
}

.settings-field-row{
  display:flex;
  gap:10px;
  align-items:center;
  margin-bottom:10px;
}

.settings-field-input{
  flex:1;
  width:100%;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:9px 12px;
  color:var(--text);
  font-size:13px;
  font-family:'Space Grotesk',sans-serif;
}

.settings-inline-form{
  display:flex;
  gap:10px;
  align-items:center;
}

.verify-badge{
  font-size:11px;
  padding:3px 9px;
  border-radius:10px;
  background:var(--resolved-dim);
  color:var(--resolved);
  white-space:nowrap;
}

.verify-badge.pending{
  background:var(--accent-dim);
  color:var(--accent);
}

.dns-hint{
  font-size:11px;
  color:var(--text-muted);
  background:var(--surface);
  border:1px dashed var(--border);
  border-radius:8px;
  padding:10px 12px;
  margin-top:6px;
}

.logo-row{
  display:flex;
  align-items:center;
  gap:14px;
}

.logo-drop{
  width:64px;
  height:64px;
  border-radius:10px;
  border:1px dashed var(--border);
  display:flex;
  align-items:center;
  justify-content:center;
  color:var(--text-muted);
  font-size:11px;
  text-align:center;
  flex-shrink:0;
}

.logo-preview{
  width:64px;
  height:64px;
  border-radius:10px;
  object-fit:cover;
  border:1px solid var(--border);
  flex-shrink:0;
}

.logo-btn{
  font-size:12px;
  padding:7px 14px;
  border-radius:8px;
  border:1px solid var(--border);
  background:var(--surface-raised);
  color:var(--text-secondary);
  cursor:pointer;
  display:inline-block;
}

.logo-btn:hover{
  color:var(--text);
}

.save-btn{
  margin-top:20px;
  padding:10px 18px;
  border-radius:8px;
  background:var(--accent);
  color:#1A1408;
  font-weight:500;
  font-size:13px;
  border:none;
  cursor:pointer;
  font-family:'Space Grotesk',sans-serif;
}

.save-btn:hover{
  filter:brightness(1.05);
}

.settings-preview-col{
  position:sticky;
  top:0;
}

.preview-label{
  font-size:11px;
  color:var(--text-muted);
  text-transform:uppercase;
  letter-spacing:0.06em;
  margin-bottom:10px;
}

.preview-card{
  border:1px solid var(--border);
  border-radius:12px;
  overflow:hidden;
  background:var(--bg);
}

.preview-topbar{
  padding:10px 14px;
  border-bottom:1px solid var(--border);
  background:var(--surface);
  display:flex;
  align-items:center;
  gap:8px;
}

.preview-mark{
  width:16px;
  height:16px;
  border-radius:4px;
  flex-shrink:0;
}

.preview-brand{
  font-size:12px;
  font-weight:500;
  color:var(--text);
}

.preview-body{
  padding:16px;
  display:flex;
  flex-direction:column;
  gap:8px;
}

.preview-bar{
  height:8px;
  border-radius:4px;
  background:var(--surface-raised);
}

.preview-bar.short{
  width:60%;
}

.preview-pin{
  width:10px;
  height:10px;
  border-radius:50%;
  flex-shrink:0;
}

.preview-note{
  font-size:11px;
  color:var(--text-muted);
  margin-top:10px;
}

@media (max-width: 860px){
  .settings-grid{
    grid-template-columns:1fr;
  }
  .settings-preview-col{
    position:static;
  }
}

/* -----------------------------------------------------------------------
   Pre-auth pages restyle (frontend-brand-guardian, 2026-07-21).
   Per downloads/mockups/portask-login.html + portask-signup-reset.html
   (login/signup states only — reset states are explicitly out of scope,
   see docs/brandbook.md's new Phase 7 section). Replaces the old
   generic `.auth-shell`/`.auth-card` (400px, Phase 1 stand-in) treatment
   on login/signup/invite-accept-signup ONLY with the mockup's exact
   340px centered-card composition. `.auth-shell`/`.auth-card` themselves
   are NOT removed/redefined here — other pages (dashboard, workspace
   settings stand-ins, etc.) still use them unchanged; this is a set of
   additive, more specific classes layered on top for just these 3 pages.
   ----------------------------------------------------------------------- */

.auth-card--compact{
  width:100%;
  max-width:340px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:12px;
  padding:28px 26px;
}

/* Mockup's `.logo-row` is visually identical to the existing
   `.brand-row` (brand_mark.html) except centered. `brand_mark.html` is
   a stable, unmodified drop-in partial (per its own docstring) so
   rather than editing it to accept a modifier class, these 3 restyled
   pages wrap its include in a plain `<div class="brand-row--centered">`
   — this rule targets the nested `.brand-row` as a descendant so the
   wrapper itself needs no display/flex properties of its own. */
.brand-row--centered .brand-row{
  justify-content:center;
  margin-bottom:22px;
}

.auth-heading{
  font-size:15px;
  font-weight:500;
  text-align:center;
  color:var(--text);
  margin:0 0 2px;
}

.auth-subheading{
  font-size:12px;
  color:var(--text-muted);
  text-align:center;
  margin:0 0 22px;
}

.auth-form--compact{
  display:flex;
  flex-direction:column;
}

.auth-form--compact .field-label{
  margin-bottom:6px;
}

.auth-form--compact input{
  width:100%;
  background:var(--surface-raised);
  border:1px solid var(--border);
  border-radius:8px;
  padding:10px 12px;
  color:var(--text);
  font-size:13px;
  margin-bottom:14px;
  font-family:'Space Grotesk',sans-serif;
}

.auth-form--compact input::placeholder{
  color:var(--text-muted);
}

.auth-form--compact input:focus{
  outline:none;
  border-color:var(--accent);
}

.auth-form--compact input:disabled{
  color:var(--text-muted);
  cursor:not-allowed;
}

/* Visual-only "Forgot password?" link (see docs/brandbook.md's new
   pre-auth section + login.html's own comment) — dead link, reset flow
   is an explicitly future phase. Styled per the mockup exactly. */
.auth-forgot-row{
  display:flex;
  justify-content:flex-end;
  margin:-6px 0 16px;
}

.auth-forgot-row a{
  font-size:11.5px;
  color:var(--text-muted);
  text-decoration:underline;
}

.auth-forgot-row a:hover{
  color:var(--text-secondary);
}

.auth-submit-btn{
  width:100%;
  padding:11px;
  border-radius:8px;
  font-weight:500;
  font-size:13px;
  border:none;
  cursor:pointer;
  margin-bottom:14px;
  margin-top:0;
  background:var(--accent);
  /* text color set inline per the brandbook's contrast rule (Phase 5
     extension) via `brand.mark_text_color`, not hardcoded here — same
     reasoning as .btn-primary needing the same treatment; kept as a
     plain color fallback only in case a caller forgets the inline
     style. */
  color:#1A1408;
  font-family:'Space Grotesk',sans-serif;
}

.auth-submit-btn:hover{
  filter:brightness(1.05);
}

.auth-footer-note{
  font-size:11.5px;
  color:var(--text-muted);
  text-align:center;
  margin:0;
}

.auth-footer-note a{
  color:var(--text-secondary);
  text-decoration:underline;
}

.auth-footer-note a:hover{
  color:var(--text);
}

/* Accept-invite state's "invited by <studio>" pill — reuses the
   existing accent-dim/accent badge pairing already established for
   status pills elsewhere in the system (see docs/brandbook.md's
   dim-bg/base-fg pattern), just centered per the mockup's `.accept`
   state. */
.invite-badge{
  font-size:11px;
  color:var(--accent);
  background:var(--accent-dim);
  padding:4px 10px;
  border-radius:10px;
  display:inline-block;
  margin-bottom:14px;
}

.invite-badge-row{
  text-align:center;
}
