/* ===========================================================================
   THE DESIGN SYSTEM, SHARED WITH THE OTHER TWO
   Colours, type, depth and motion mirror sales-command-center/src/app/globals.css
   and perceptionismlabkpis/public/index.html so all three read as one product.
   Change them THERE first, then here, or the three will drift.

   Layout deliberately does NOT match, exactly as the KPI dashboard's layout
   deliberately does not match the Command Center's. This app is a sidebar, a
   month of week trays and a kanban board; none of that exists on the other two.

   2026-08-27: before this, the page was a warm near-black (#090807) under a
   warm gold (#c9a84c) in DM Sans, with FOURTEEN text sizes starting at 8px --
   its own product, sitting behind the same login as two others that had
   already settled this. Same fix the KPI dashboard made on 2026-08-19.
   =========================================================================== */
:root{
  /* PAGE AND SURFACES */
  --bg:#09090b;--bg2:#111113;--bg3:#1a1a1f;
  --sf:#0f0f12;    /* the surface a card or panel sits on */
  --rs:#1a1a1f;    /* one step up: hover fills, chip fills, inset wells */
  --bd:#ffffff0f;--bdL:#ffffff1f;
  --lift:0 1px 2px #00000040,0 12px 32px -16px #000000cc;

  /* TEXT -- four steps, and only the first three may carry words.
     --txD is decoration: separators, units, a dash standing in for a number.
     Anything a person has to READ uses --txM or brighter. */
  --tx:#fafaf9;--txS:#d4d4d8;--txM:#a1a1aa;--txD:#71717a;

  /* GOLD is the brand and carries no verdict. */
  --gd:#d4af37;--gd3:#f0d98a;--gd4:#e5c158;--gd6:#b8942c;
  --gdD:rgba(212,175,55,.12);--gdB:#d4af3733;
  --gdInk:#17120a;  /* text that sits ON a gold fill */

  /* THE SEMANTIC PAIR -- the only two colours here that mean good and bad, so
     they are never used as decoration. Deliberately desaturated: a saturated
     green beside this gold reads as a traffic light. */
  --gn:#6ee7a8;--gn2:rgba(110,231,168,.12);
  --rd:#f4776b;--rd2:rgba(244,119,107,.12);
  --am:#f59e0b;--am2:rgba(245,158,11,.12);

  /* CATEGORICAL -- pillars, formats, platforms, pipeline stages, trackers.
     Ten hues that stay apart at a 7px dot, all pulled to the lightness and
     saturation of the pair above so nothing outshouts the gold. The matching
     list in src/app.jsx holds the same values as literals, because a tracker
     colour is saved to the database and a CSS variable cannot be. */
  --bl:#7ba8f2;--pr:#c19ae8;--tl:#6ed4d4;--or:#f5a56b;--pk:#f490b6;

  /* TYPE -- three sizes, and only three. A number is not text and has its own
     scale (20 / 26 / 42, mono, tabular). Hierarchy below these is carried by
     weight, case and colour, never by another size.

     2026-09-04: body was 13 and lead 15, and the label step was carrying 83 of
     the stylesheet's 108 size declarations -- table cells, empty states and
     video titles all sat at 11px in the mono face, so the app read as a machine
     readout and nothing in it could stand out. The label step is now for LABELS
     only: a word or two, upper case, in mono. Anything that is a sentence or a
     name takes --t-body in the sans face. */
  --t-label:11px;--t-body:14px;--t-lead:16px;
  --sn:'Bricolage Grotesque',system-ui,-apple-system,sans-serif;
  --mn:'JetBrains Mono',ui-monospace,'SF Mono',monospace;
  --sidebar:180px;

  /* SPACING, RADIUS, DEPTH */
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--s6:32px;
  /* THE PAGE BOX. Nothing had a maximum width, so on a 1920 screen an Overview
     row was a short sentence hard against the left edge and its chevron about
     1500px away on the right, and a stat tile 550px wide held a single digit.
     --page caps the measure and --pad is the gutter; both are spent through the
     one padding-inline rule further down, which keeps the top bar's rule and
     the calendar's dividers running full width while their CONTENTS line up
     with the page. */
  --page:1440px;--pad:24px;
  /* Four real steps. --r3 and --r5 are aliases kept so the names already in
     the sheet keep resolving; nothing new should reach for them. */
  --r1:6px;--r2:8px;--r3:8px;--r4:12px;--r5:12px;--r6:16px;
  --e1:0 1px 2px rgba(0,0,0,.4);
  --e2:var(--lift);
  --e3:0 8px 24px rgba(0,0,0,.5);
  --e4:0 24px 70px rgba(0,0,0,.65);

  /* A REEL CARD IS AN OBJECT, not text floating on the page. This is the one
     place the app keeps a fill LIGHTER than the shared card surface, because a
     card sits inside a week tray which already sits on the page -- give it
     --sf and it disappears again, which is what it used to do. Same lightness
     the old warm #221e19 measured (1.21:1 against the page), in the shared
     neutral hue, and now with the shared lift under it rather than only on
     hover. */
  --sf2:#1f1f24;--edge:#ffffff26;--edgeS:#ffffff3d;
}
*{margin:0;padding:0;box-sizing:border-box}
/* The dot grid is the one texture on the other two dashboards you can
   actually see, and it is what stops a near-black page reading as a void. */
body{background:var(--bg);color:var(--tx);font-family:var(--sn);font-size:var(--t-body);line-height:1.5;-webkit-font-smoothing:antialiased;
  background-image:radial-gradient(circle,#ffffff08 1px,transparent 1px);background-size:24px 24px}
/* Numbers line up column to column, as they do on the other two. */
.tabular,.oi-v,.ov-strip-v,.rc-pv,.goal-vals,.tr-v{font-variant-numeric:tabular-nums}
::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff15;border-radius:var(--r1)}::-webkit-scrollbar-thumb:hover{background:#ffffff25}
button,input,textarea,select{font-family:var(--sn)}textarea{resize:vertical}

/* Nothing showed a focus ring, so keyboard users had no idea where they were.
   :focus-visible keeps it off for mouse clicks and on for keyboard traversal. */
:focus-visible{outline:2px solid var(--gd);outline-offset:2px;border-radius:var(--r1)}
.rc:focus-visible,.addc:focus-visible{outline-offset:-2px}
/* Skip link: first tab stop, lets keyboard users jump past the sidebar. */
.skip{position:absolute;left:-9999px;top:0;z-index:5000;background:var(--gd);color:var(--gdInk);
  padding:8px 14px;border-radius:0 0 6px 0;font-family:var(--mn);font-size:var(--t-label);font-weight:700}
.skip:focus{left:0}

/* === LAYOUT === */
/* 100vh on a phone is the height with the browser's toolbars HIDDEN, so a
   full-height box runs under them. dvh is the height actually on screen; the
   vh line stays first as the fallback for anything that has not got dvh. */
.app-shell{display:flex;min-height:100vh;min-height:100dvh}
.sidebar{width:var(--sidebar);background:#0b0b0e;border-right:1px solid var(--bd);display:flex;flex-direction:column;position:fixed;top:0;left:0;bottom:0;z-index:200}
.sb-logo{padding:20px 18px 6px;font-family:var(--mn);font-size:var(--t-label);font-weight:700;color:var(--tx);letter-spacing:.04em}
.sb-sub{padding:0 18px 18px;font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txM)}
.sb-section{padding:0 10px;margin-top:6px}
.sb-section-t{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txM);padding:8px 8px 4px;font-weight:500}
.sb-item{position:relative;display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r4);cursor:pointer;font-size:var(--t-body);font-weight:500;color:var(--txM);transition:color .2s,background-color .2s,transform .2s;border:none;background:none;width:100%;text-align:left}
.sb-item:hover{color:var(--tx);background:#ffffff0a}
.sb-item.on{color:var(--gd4);background:var(--gdD);font-weight:500}
/* The bar is what makes the current view readable at a glance once the
   labels are gone at 900px, where a gold icon on its own is easy to miss.
   It is drawn on EVERY item, not only the current one, and scaled to nothing
   when that item is not selected -- a pseudo-element that only exists on .on
   pops into place with no way to transition, because there is no previous
   state for the browser to animate from. Scaling one that is always there
   costs nothing to paint and lets it grow. */
.sb-item::before{content:'';position:absolute;left:0;top:50%;width:2px;height:16px;border-radius:0 2px 2px 0;background:var(--gd);transform:translateY(-50%) scaleY(0);transition:transform .2s ease-out}
.sb-item.on::before{transform:translateY(-50%) scaleY(1)}
.sb-item.on .sb-icon{opacity:1}
.sb-icon{width:14px;height:14px;opacity:.5;flex-shrink:0}
.sb-badge{margin-left:auto;font-size:var(--t-label);font-family:var(--mn);padding:1px 5px;border-radius:var(--r1);font-weight:600}
.sb-clients{margin-top:auto;padding:10px;border-top:1px solid var(--bd)}
.sb-cl{display:flex;align-items:center;gap:7px;padding:6px 8px;border-radius:var(--r2);cursor:pointer;font-size:var(--t-label);font-weight:500;color:var(--txS);transition:color .12s,background-color .12s}
.sb-cl:hover{background:var(--rs);color:var(--tx)}
.sb-cl.on{color:var(--gd)}
.sb-cl-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.sb-cl-add{background:none;border:1px dashed var(--bd);border-radius:var(--r2);padding:5px 8px;cursor:pointer;color:var(--txM);font-size:var(--t-label);width:100%;margin-top:4px;font-family:var(--mn);letter-spacing:.06em;transition:color .15s,border-color .15s}
.sb-cl-add:hover{border-color:var(--txS);color:var(--txS)}
.sb-footer{padding:10px;border-top:1px solid var(--bd)}
.sb-user{display:flex;align-items:center;gap:8px;padding:6px 8px}
.sb-user-av{width:28px;height:28px;border-radius:50%;background:var(--gd);display:flex;align-items:center;justify-content:center;font-size:var(--t-label);font-weight:700;color:var(--gdInk);flex-shrink:0}
.sb-user-name{font-size:var(--t-label);font-weight:600;color:var(--tx)}
.sb-user-role{font-size:var(--t-label);color:var(--txM);font-family:var(--mn);letter-spacing:.06em}
/* min-width:0 matters. A flex item defaults to min-width:auto, which means it
   refuses to shrink below its content. The calendar week strips and the pipeline
   columns are fixed-width rows, so without this the whole document grew wider
   than the window and pushed the month stepper in .topbar off the right edge --
   permanently on Pipeline, and on Calendar at any width under 1100px. */
.main-area{margin-left:var(--sidebar);flex:1;min-width:0;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}

/* === TOP BAR (inside main) === */
.topbar{padding:14px 24px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--bd);background:var(--bg);position:sticky;top:0;z-index:100;gap:10px;flex-wrap:wrap}
.topbar-l{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.topbar-title{font-size:18px;font-weight:700}
.topbar-r{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.plat-tabs{display:flex;gap:4px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r4);padding:3px}
.plat-tab{padding:5px 12px;border-radius:var(--r2);font-size:var(--t-label);font-weight:500;font-family:var(--sn);letter-spacing:0;text-transform:none;cursor:pointer;border:none;background:none;color:var(--txM);transition:color .2s,background-color .2s,transform .2s;display:flex;align-items:center;gap:5px}
.plat-tab.on{background:#ffffff0f;color:var(--tx)}
.plat-tab:hover:not(.on){color:var(--txS)}
.plat-dot{width:5px;height:5px;border-radius:50%}
.topbar-date{font-size:var(--t-label);color:var(--txS);font-family:var(--mn)}

/* === SHARED UI === */
.btn{padding:5px 12px;border-radius:var(--r2);font-size:var(--t-label);cursor:pointer;font-family:var(--sn);letter-spacing:0;font-weight:500;white-space:nowrap;border:1px solid var(--bd);background:none;color:var(--txM);transition:color .2s,background-color .2s,border-color .2s,transform .2s}
.btn:hover{border-color:var(--bdL);color:var(--txS)}
/* A DISABLED BUTTON HAS TO LOOK DISABLED. There was no rule for this, so every
   `disabled` button in the app rendered at full strength with a pointer cursor
   -- indistinguishable from a working one. PUBLISH NOW is disabled while the
   video is still being resolved and whenever it cannot be, which is precisely
   when somebody clicks it repeatedly and concludes the app is broken. */
.btn:disabled,.btn[disabled]{opacity:.4;cursor:not-allowed}
.btn:disabled:hover,.btn[disabled]:hover{background:var(--bg);border-color:var(--bd);color:var(--txS)}
.btn-g:disabled:hover,.btn-g[disabled]:hover{background:var(--gd);border-color:var(--gd);color:var(--gdInk)}
.btn-g{background:var(--gd);color:var(--gdInk);border-color:var(--gd);font-weight:600}
.btn-g:hover{background:var(--gd4);color:var(--gdInk)}
.btn-gn{border-color:var(--gn2);color:var(--gn)}
.btn-gn:hover{border-color:var(--gn);color:var(--gn)}
.btn-rd{border-color:var(--rd2);color:var(--rd)}
.btn-rd:hover{border-color:var(--rd);color:var(--rd)}
/* The 'this one is selected' chip, borrowed verbatim from the other two. */
.btn.on{background:var(--gdD);color:var(--gd4);border-color:var(--gdB)}
.tabs{display:flex;gap:4px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r4);padding:3px}
.tab{padding:5px 12px;border-radius:var(--r2);font-size:var(--t-label);font-weight:500;font-family:var(--sn);letter-spacing:0;text-transform:none;cursor:pointer;border:none;background:none;color:var(--txM);transition:color .2s,background-color .2s,transform .2s}
.tab.on{background:#ffffff0f;color:var(--tx)}
.tab:hover:not(.on){color:var(--txS)}
.ov{position:fixed;inset:0;z-index:2000;background:rgba(0,0,0,.85);backdrop-filter:blur(4px);display:flex;justify-content:center;padding:12px;overflow-y:auto;overscroll-behavior:contain}
.mdl{background:var(--sf);border:1px solid var(--bd);border-radius:var(--r6);box-shadow:var(--e4);width:100%;max-width:640px;margin:auto;overflow:hidden}.mdl-s{max-width:400px}
.mh{padding:14px 20px;border-bottom:1px solid var(--bd);display:flex;justify-content:space-between;align-items:center}
/* This was a bare glyph with no box: 9px wide by 18px tall, which is smaller
   than the accessibility floor of 24 and a quarter of the 44 a thumb needs. */
.mx{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;margin:-6px -8px -6px 0;background:none;border:none;border-radius:var(--r2);color:var(--txM);font-size:18px;cursor:pointer;line-height:1}
.mx:hover{background:var(--rs);color:var(--tx)}
.mb{padding:16px 20px;display:flex;flex-direction:column;gap:14px;max-height:78vh;max-height:78dvh;overflow-y:auto;overscroll-behavior:contain}
.mf{padding:12px 20px;border-top:1px solid var(--bd);display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap;position:sticky;bottom:0;background:var(--sf)}
.mf-g{display:flex;gap:4px;flex-wrap:wrap}
.fl{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txM);margin-bottom:4px;display:block;font-weight:500}
.fi{width:100%;padding:7px 10px;background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1);color:var(--tx);font-size:var(--t-body);outline:none}.fi:focus{border-color:var(--bdL)}.fi.hk{font-size:var(--t-lead);font-weight:700;padding:10px 12px}.fi.ta{min-height:70px;line-height:1.7}.fi.ta-s{min-height:36px}
.fr{display:grid;grid-template-columns:1fr 1fr;gap:8px}.fr4{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:8px}
.sec{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txS);font-weight:600;margin-top:4px;padding-top:10px;border-top:1px solid var(--bd)}
.pg{display:flex;gap:3px;flex-wrap:wrap}.pl{padding:3px 7px;border-radius:var(--r1);font-size:var(--t-label);font-weight:700;letter-spacing:.04em;cursor:pointer;font-family:var(--mn);border:1px solid var(--bd);background:transparent;color:var(--txM);transition:color .12s,background-color .12s,border-color .12s,transform .12s;display:inline-flex;align-items:center;gap:3px}.pl.on{color:var(--gdInk)}
.cfm{position:fixed;inset:0;z-index:3000;background:rgba(0,0,0,.9);display:flex;align-items:center;justify-content:center}.cfm-b{background:var(--sf);border:1px solid var(--bd);border-radius:var(--r2);padding:22px 26px;max-width:320px;text-align:center}.cfm-b p{font-size:var(--t-body);color:var(--txS);margin-bottom:14px}
.toast{position:fixed;bottom:16px;left:50%;transform:translateX(-50%);background:var(--gd);color:var(--gdInk);padding:7px 16px;border-radius:var(--r2);font-size:var(--t-label);font-weight:700;z-index:4000;font-family:var(--mn);animation:fu .3s}
@keyframes fu{from{opacity:0;transform:translateX(-50%) translateY(8px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}

/* === OVERVIEW === */
.ov-page{padding:var(--pad)}
.ov-greeting{font-size:22px;font-weight:800;margin-bottom:3px}
.ov-sub{font-size:var(--t-body);color:var(--txS);margin-bottom:20px}
/* MONTH SO FAR. Every client together, three plain figures rather than cards:
   it is the context for the queue underneath, not the point of the page. */
.ov-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:14px}
.ov-strip-i{background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);box-shadow:var(--lift);padding:14px 16px}
.ov-strip-v{font-size:26px;font-weight:700;line-height:1;font-family:var(--mn);letter-spacing:-.02em}
.ov-strip-l{font-size:var(--t-label);font-family:var(--mn);letter-spacing:.1em;text-transform:uppercase;color:var(--txM);margin-top:7px;font-weight:500}
.ov-strip-c{font-size:var(--t-body);color:var(--txS);margin-top:8px;line-height:1.5}
/* ONE CLIENT'S MONTH. The bar fills with what is already out; the pale line
   across it marks how far into the plan the calendar has got, so a bar short of
   the line is a month running late -- readable without stopping to do sums. */
.pace-row{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--bd);cursor:pointer;flex-wrap:wrap;border-radius:var(--r1);transition:background .12s}
.pace-row:last-child{border-bottom:none}
.pace-row:hover{background:rgba(255,255,255,.03)}
.pace-name{display:flex;align-items:center;gap:7px;font-size:var(--t-body);font-weight:700;width:130px;flex-shrink:0}
.pace-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.pace-bar{position:relative;display:block;flex:1 1 110px;min-width:90px;height:7px;border-radius:var(--r1);background:var(--bg);overflow:hidden}
.pace-fill{position:absolute;left:0;top:0;bottom:0;border-radius:var(--r1);transition:width .3s}
.pace-tick{position:absolute;top:0;bottom:0;width:2px;border-radius:1px;background:var(--tx);opacity:.55}
.pace-count{font-size:var(--t-body);font-family:var(--mn);color:var(--txS);width:64px;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums}
.pace-flag{font-size:var(--t-label);font-family:var(--mn);font-weight:700;letter-spacing:.06em;padding:3px 8px;border-radius:var(--r1);flex-shrink:0;min-width:80px;text-align:center}
/* order:1 puts the rate hint last, so IT is what drops to a second line when
   the row runs out of width -- the Overview's lower cards are half the page
   now, and without this the piece that wrapped was "1 ready", which read as a
   stray fragment under the bar. */
.pace-note{font-size:var(--t-body);color:var(--txM);flex:1 1 90px;min-width:70px;order:1}
.pace-ready{font-size:var(--t-body);color:var(--txM);flex-shrink:0}
.ov-card{background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);box-shadow:var(--lift);overflow:hidden}
/* MONTH PACE AND REVENUE SHARE A ROW. Stacked, the Overview was five
   full-width bands one under another, most of them holding a single line of
   content, and the page ran out two thirds of the way down every screen. Side
   by side they fill the row and the page ends where the content does. Revenue
   opened is a four-field form per client, so it takes the whole row back when
   it is expanded. */
.ov-lower{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.ov-lower.ov-lower-wide{grid-template-columns:1fr}
@media(max-width:900px){.ov-lower{grid-template-columns:1fr}}
.ov-card-full{grid-column:1/-1}
.ov-card-h{padding:12px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--bd)}
.ov-card-t{font-size:var(--t-body);font-weight:700}
.ov-card-act{font-size:var(--t-label);color:var(--txM);background:none;border:none;cursor:pointer;font-family:var(--mn);letter-spacing:.06em;font-weight:600;transition:color .15s,transform .12s}
.ov-card-act:hover{color:var(--gd)}
.ov-card-b{padding:12px 16px}
.ov-empty{padding:20px;text-align:center;color:var(--txM);font-size:var(--t-body)}

/* === CALENDAR === */
.mo{display:flex;align-items:center;gap:8px}.mo button{background:none;border:1px solid var(--bd);border-radius:var(--r1);color:var(--txS);cursor:pointer;padding:3px 7px;font-size:var(--t-label)}
.mo span{font-size:var(--t-body);font-weight:600;min-width:110px;text-align:center}
.sbar{padding:7px 20px;border-bottom:1px solid var(--bd);display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:var(--t-label)}.sbar b{font-size:var(--t-lead);font-weight:800}
.sep{color:var(--bd)}
/* A week is a tray, the same way a pipeline stage is a tray. Before this the
   calendar was the only view in the app that put content straight onto the page
   background with no surface under it, which is most of why it read as flat. */
.wk{min-width:0;background:#ffffff05;border:1px solid var(--bd);border-radius:var(--r6);padding:var(--s3)}
/* ADD WEEK is a month-level control and is no longer a child of the .cal-wrap
   grid at all. It used to span 1/-1 to avoid being orphaned under W1, and an
   item spanning every column is exactly what forced auto-fit to keep building
   tracks past the last week: at 1920 the month laid out as six 271px columns
   for four weeks and bunched into the left two thirds of the screen. Out of the
   grid, those four weeks measure 414px each and fill the row. */
.wk-addw{display:flex;justify-content:flex-end;padding-bottom:48px}
/* Two fixed-height rows. The old header was one wrapping flex row, so headers
   measured 37/47/28/28px across the four weeks and the card grids underneath
   started at four different heights. Fixed rows make them line up. */
.wk-h{padding:0 2px var(--s2);border-bottom:1px solid var(--bd);margin-bottom:var(--s3)}
.wk-h-r{display:flex;align-items:center;gap:var(--s2)}
/* Row 1 is a fixed-height row so the four week columns line up. At the shared
   11px label size the pieces in it total exactly the column width, so each
   one wrapped to two lines and W4 -- the only week carrying a THIS WEEK chip
   -- grew 16px taller than its neighbours. Nothing in this row may wrap; the
   date range truncates instead, and it is the one piece the week number and
   the chip already say. */
/* This row wraps rather than clips, for the same reason the tally row below it
   does. It is W1, the dates, THIS WEEK, the count, the fold and the delete in a
   250px column -- on the current week that is more than fits, and nowrap meant
   the dates ellipsed away to "Sep..." to make room. A second line costs a few
   pixels of header; a hidden date range costs you the week you were looking
   for. */
.wk-h-r1{min-height:22px;flex-wrap:wrap;row-gap:4px}
.wk-now,.wk-ct,.wk-n{white-space:nowrap;line-height:1.2}
.wk-range{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
/* THESE TWO USED TO BE nowrap + overflow:hidden, which silently ATE COUNTS.
   A week showing all six stages needs 344px of tallies; a column is 250px on a
   desktop grid and 270px on a 320px phone, so two of the six just disappeared
   -- no ellipsis, no scrollbar, nothing to tell you a number was missing. A
   tally row that wraps to a second line is the whole fix. */
.wk-h-r2{min-height:17px;margin-top:3px;flex-wrap:wrap}
/* FOLD A WEEK AWAY. Its header stays -- dates, count, stage tallies -- so a
   folded month still reads as a month and week 4 is one tap away instead of
   three screens of scrolling. */
.wk-fold{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;flex-shrink:0;margin-left:-3px;border:none;background:none;border-radius:var(--r1);color:var(--txM);cursor:pointer;transition:color .12s,background .12s}
.wk-fold:hover{color:var(--tx);background:var(--rs)}
.wk-shut{padding:10px 8px;text-align:center;font-size:var(--t-body);color:var(--txM);opacity:.7;cursor:pointer;border:1px dashed var(--bd);border-radius:var(--r3)}
.wk-shut:hover{opacity:1;border-color:var(--bdL)}
.wk-n{font-size:var(--t-body);font-weight:800;color:var(--gd);font-family:var(--mn)}
.wk-eb{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;flex-shrink:0;border:1px solid transparent;border-radius:var(--r1);background:none;color:var(--txM);cursor:pointer;font-size:var(--t-label);line-height:1;transition:color .12s,border-color .12s,background .12s}
.wk-eb:hover{color:var(--rd);border-color:rgba(244,119,107,.4);background:rgba(244,119,107,.1)}
/* Count as a chip, matching .pipe-col-ct. */
.wk-h-end{display:inline-flex;align-items:center;gap:var(--s2);margin-left:auto;flex-shrink:0}
.wk-ct{font-size:var(--t-label);font-family:var(--mn);color:var(--txM);font-weight:600;background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1);padding:1px 6px;flex-shrink:0}
/* One layout at every width: weeks are columns in an auto-fitting grid, and a
   week is always a vertical stack of cards. The old file had three hand-tuned
   breakpoints and a horizontal filmstrip below 1100px, where a card measured
   1168px wide and a week scrolled sideways for 5912px -- one card visible at a
   time. auto-fit lands 4 columns on a laptop, 2-3 in the middle, 1 on a phone,
   with no cliff between them. min(260px,100%) so a container narrower than the
   track cannot overflow. */
.cal-wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));gap:var(--s4);align-items:start;padding:var(--pad) var(--pad) var(--s4)}
.wk-g{padding:2px;display:flex;flex-direction:column;gap:var(--s2)}
/* --sf2 and --edge come from phase 1. The old fill was 1.09:1 against the page
   and the old border 1.13:1, so a card had no visible edge at all -- it was text
   floating on black. Now the object exists before you read anything in it. */
/* -webkit-touch-callout / user-select: the card is marked draggable, so a long
   press on a phone popped iOS's text-selection menu over it instead. */
.rc{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;
  background:var(--sf2);border:1px solid var(--edge);border-radius:var(--r4);padding:var(--s3);cursor:pointer;flex:0 0 auto;box-shadow:var(--e1);transition:border-color .2s,box-shadow .2s,transform .2s;position:relative;display:flex;flex-direction:column;min-height:112px}
/* .rec used to also set a rgba(...,.025) green fill, which measured as black and
   would now punch a hole in the new surface. The green check chip already says
   "recorded"; phase 3 gives it a proper treatment. */
.rc:hover{border-color:var(--edgeS);transform:translateY(-1px);box-shadow:var(--e2)}
.rc:active{transform:translateY(0)}
/* Recorded, outlier and priority are three unrelated facts that were all
   writing to border-color, so they overwrote each other -- a priority reel that
   was also an outlier silently lost its priority marker. Each now owns its own
   channel: border for recorded/outlier, a left stripe for priority (the same
   stripe .pipe-card-pri uses), and the corner chip for recorded. */
.rc.rec{border-color:rgba(110,231,168,.3)}
.rc.out{border-color:var(--gd);box-shadow:0 0 12px rgba(212,175,55,.1)}
.rc.rc-pri{border-left-width:3px;border-left-color:var(--rd);padding-left:10px}
.rc.dragging{opacity:.35;transform:scale(.97);border-style:dashed;box-shadow:none}
.rc.rc-drop::before{content:'';position:absolute;left:6px;right:6px;top:-6px;height:4px;border-radius:2px;background:var(--gd);box-shadow:0 0 8px rgba(212,175,55,.5)}
/* Drop targets speak one language across the app: dashed gold outline plus a
   tint for "into this container", a solid gold bar for "at this position".
   .wk-g had the tint and no outline while .pipe-drop-zone had both. The
   transparent border is in the base so turning it on shifts nothing. */
.wk-g{border:1px dashed transparent;border-radius:var(--r3)}
.wk-g.wk-drop{border-color:var(--gdB);background:var(--gdD)}
/* Empty week. .pipe-drop-zone:empty::before already does this for the pipeline,
   but .wk-g is never :empty -- the add pill lives inside it -- so this is
   rendered from the JSX instead. */
.wk-empty{padding:16px 8px;text-align:center;font-size:var(--t-body);color:var(--txM);opacity:.75}

.rc-hook{font-size:var(--t-lead);font-weight:600;line-height:1.4;font-family:var(--sn);margin-bottom:var(--s2);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.rc-hook.mt{color:var(--txM);font-style:italic;font-weight:400}
.rc-meta{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin-top:auto}
/* A YouTube video's planned thumbnail, across the top of its card. Cropped to
   16:9 here, where a screenshot with a stray border would otherwise make one
   card taller than the rest; the modal shows it whole. */
.rc-thumb{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:var(--r2);margin-bottom:var(--s2);background:var(--rs)}
.rc-thumb.thumb-gone{display:flex;align-items:center;justify-content:center;font-family:var(--mn);font-size:10px;letter-spacing:.06em;color:var(--txD);text-align:center;padding:0 6px}
.rc-tag{font-size:var(--t-label);font-family:var(--mn);padding:2px 6px;border-radius:var(--r1);font-weight:600;letter-spacing:.04em}
.rc-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;display:inline-block}
/* An unset tag. Deliberately the quietest thing on the card -- it marks work
   somebody still has to do, not a failure, and on a client whose pillars were
   renamed it can be most of a month. Loud here would just teach you to skim
   the row it sits in. */
.rc-tag-unset{color:var(--txD);background:none;border:1px dashed var(--bd);font-weight:500}
.rc-rec-chip{position:absolute;top:9px;right:9px;width:15px;height:15px;border-radius:50%;background:var(--gn);display:flex;align-items:center;justify-content:center}
.rc.rec .rc-hook{padding-right:16px}
/* :focus-within so the frame.io link and the record toggle are reachable by
   keyboard -- they were hover-only, which meant Tab landed on invisible targets. */
.rc-icons{display:flex;gap:3px;align-items:center;margin-left:auto;opacity:0;transition:opacity .15s}.rc:hover .rc-icons,.rc:focus-within .rc-icons{opacity:1}
.drv{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:var(--r1);background:rgba(193,154,232,.1);border:1px solid rgba(193,154,232,.16);cursor:pointer;text-decoration:none}.drv svg{width:8px;height:8px}
.rtg{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:var(--r1);cursor:pointer;border:1px solid var(--bd);background:transparent;color:var(--txM)}.rtg.on{background:var(--gn2);border-color:rgba(110,231,168,.35);color:var(--gn)}.rtg:disabled{cursor:default}.rtg svg{width:8px;height:8px}
/* POST, on a card that is ready to go out. It sits in .rc-icons with the other
   two but must NOT inherit their hover-to-reveal: those are a link and a toggle
   you go looking for, this is the action the card exists to offer by the time it
   is drawn, and an invisible one would never be found. Green rather than the
   gold used everywhere else, because it is the only control on a card that
   publishes to a live account. */
.rc-post{opacity:1;display:inline-flex;align-items:center;justify-content:center;height:16px;padding:0 6px;border-radius:var(--r1);cursor:pointer;font-family:var(--mn);font-size:var(--t-label);letter-spacing:.08em;font-weight:700;color:#09090b;background:var(--gn);border:1px solid var(--gn)}
.rc-post:hover{filter:brightness(1.08)}
.rc:has(.rc-post) .rc-icons{opacity:1}
/* Four numbers at the same size is zero numbers. The first cell is the
   platform's headline metric (plays / views -- it is already cardPerf[0]), so it
   gets the weight; the other three stay as supporting detail. Nothing is
   dropped, it is only ranked. */
/* The headline takes its own line and the three supporting metrics share the
   next one. Squeezing all four onto one row worked at 1440 but put "FOLLOWS"
   within a pixel or two of truncating at narrower columns, which made the whole
   layout hostage to font metrics. Two rows fit at any card width, and the
   headline reads as the headline rather than as the widest of four. */
.rc-perf{display:flex;flex-wrap:wrap;align-items:flex-end;gap:6px;margin-top:var(--s2);padding-top:var(--s2);border-top:1px solid #ffffff0f}
.rc-pc{flex:1 1 0;text-align:center;min-width:0}
.rc-pm{flex:0 0 100%;text-align:left;margin-bottom:2px}
.rc-pv{font-size:var(--t-body);font-weight:700;font-family:var(--mn);line-height:1.1;letter-spacing:-.01em}
.rc-pm .rc-pv{font-size:20px;line-height:1;letter-spacing:-.02em;font-weight:700}
.rc-pl{font-size:var(--t-label);color:var(--txM);font-family:var(--mn);letter-spacing:.04em;text-transform:uppercase;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* .tg-pri and .rc-pri were declared here and again further down with different
   values; the later pair won, so these two were dead. Removed. */
/* The bar alone was an unlabelled 3px sliver -- it read as decoration, and the
   pipeline stage is the one thing on the card you cannot otherwise see. */
.rc-stg{display:flex;align-items:center;gap:var(--s2);margin-top:9px}
.rc-stg-l{font-family:var(--mn);font-size:var(--t-label);font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--txM);flex-shrink:0}
.rc-stage{height:3px;border-radius:2px;background:var(--bd);overflow:hidden;flex:1;min-width:0}.rc-stage i{display:block;height:100%;background:var(--txM);border-radius:2px;transition:width .45s cubic-bezier(.4,0,.2,1),background-color .3s ease}.rc-stg.done .rc-stg-l{color:var(--gn)}.rc-stage.done i{background:var(--gn)}
/* Time state. The old signal for "this week" was a 1px hairline shifting from
   #1e1c18 to a 22%-alpha gold, plus a label -- which meant reading the label was
   the only way to tell. The header rule is now 2px and colour-coded the same way
   .pipe-col-hdr codes a stage: gold for now, grey for later, quieter grey for
   gone. A past week still holding unposted work turns red; that is the one
   place here where a visual state is inferred rather than stored (past week AND
   any reel below stage 5), and it is the "what am I behind on" signal. */
.wk-h{border-bottom:2px solid var(--bdL)}
.wk.cur .wk-n{color:var(--tx)}
.wk.cur .wk-h{border-bottom-color:var(--gd)}
.wk.past{background:transparent;border-color:#111113}
.wk.past .wk-h{border-bottom-color:var(--bd)}
.wk.future .wk-n{color:var(--txS)}
.wk.past .wk-n{color:var(--txM)}
.wk.past.late .wk-h{border-bottom-color:var(--rd)}
.wk.past.late .wk-n{color:var(--rd)}
.wk-now{font-size:var(--t-label);font-family:var(--mn);color:var(--gdInk);background:var(--gd);padding:2px 6px;border-radius:var(--r1);font-weight:700;letter-spacing:.06em}
.wk-range{font-size:var(--t-label);color:var(--txM);font-family:var(--mn);letter-spacing:.04em}
/* nowrap: row 2 of the header is a fixed height, so a week with many stages
   clips and falls back to the title tooltip rather than growing the header and
   knocking this column out of line with the other three. */
.wk-stats{display:flex;gap:8px;row-gap:2px;font-size:var(--t-label);font-family:var(--mn);color:var(--txM);flex-wrap:wrap;min-width:0}
.wk-stats span{white-space:nowrap}
/* .wk-g-wrap and its right-edge fade are gone. The fade hinted "this row
   scrolls sideways"; nothing scrolls sideways any more. */
.sbar-prog{display:flex;height:6px;border-radius:var(--r1);overflow:hidden;width:220px;background:var(--bd)}.sbar-prog span{display:block;height:100%}
/* .pipe-card-pri was declared here and again in the pipeline section, identically.
   Removed the duplicate; the pipeline one is the live copy. */
.addc{flex:0 0 auto;padding:9px;border:1px dashed var(--bd);border-radius:var(--r3);display:flex;align-items:center;justify-content:center;cursor:pointer;gap:6px;color:var(--txM);transition:border-color .15s,color .15s}
.addc:hover{border-color:var(--gdB);color:var(--gd)}
/* colour:inherit so the hover above actually reaches the glyph and the label. */
.addc-p{font-size:var(--t-body);color:inherit;line-height:1}
.addc-l{font-size:var(--t-label);color:inherit;font-family:var(--mn);letter-spacing:.08em}

/* === DASHBOARD === */
.dsh{padding:var(--pad);display:flex;flex-direction:column;gap:12px}
.card{background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);box-shadow:var(--lift);padding:16px 20px}.card-t{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txM);margin-bottom:12px;font-weight:500}
.og{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px}
.oi{background:var(--bg);border:1px solid var(--bd);border-radius:var(--r2);padding:10px;text-align:center}.oi-v{font-size:20px;font-weight:700;line-height:1;margin-bottom:2px;font-family:var(--mn);letter-spacing:-.02em}.oi-l{font-size:var(--t-label);font-family:var(--mn);letter-spacing:.08em;text-transform:uppercase;color:var(--txM)}.oi-d{font-size:var(--t-label);font-family:var(--mn);margin-top:3px;font-weight:600}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.tbl{width:100%;border-collapse:collapse}.tbl th{text-align:left;font-size:var(--t-label);font-family:var(--mn);letter-spacing:.08em;text-transform:uppercase;color:var(--txM);padding:6px 7px;border-bottom:1px solid var(--bd)}.tbl th.r{text-align:right}
.tbl td{font-size:var(--t-body);padding:9px 7px;border-bottom:1px solid var(--bd);color:var(--txS)}.tbl tr:last-child td{border-bottom:none}.tbl tbody tr{transition:background .12s}.tbl tbody tr:hover td{background:rgba(255,255,255,.025)}/* THE TITLE COLUMN WRAPS RATHER THAN CLIPPING. It was capped at 180px with an
   ellipsis, sized back when this text was 11px; at the body size the table's
   auto layout hands it about 230px and the hook -- the one thing in the row you
   are scanning for -- lost its last word. A second line costs a few pixels of
   row; a title cut off at "for" costs you the video. */
.tbl td.hk{color:var(--tx);font-weight:600;min-width:200px}.tbl td.r{text-align:right;font-family:var(--mn);font-size:var(--t-body)}.tbl td.hi{color:var(--gd);font-weight:700}
.tr-row{display:flex;align-items:center;gap:7px;padding:5px 0}.tr-dot{width:6px;height:6px;border-radius:2px;flex-shrink:0}.tr-nm{font-size:var(--t-body);color:var(--txS);flex:1}.tr-v{font-family:var(--mn);font-size:var(--t-body);font-weight:700;color:var(--gd4);min-width:24px;text-align:right}.tr-bar{width:80px;height:5px;background:var(--bg);border-radius:var(--r1);overflow:hidden}.tr-bf{height:100%;border-radius:var(--r1)}.tr-ct{font-family:var(--mn);font-size:var(--t-label);color:var(--txM);min-width:28px}
.bars{display:flex;gap:8px;align-items:flex-end;height:100px}.bar-c{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;height:100%}.bar-v{font-size:var(--t-label);font-weight:700;font-family:var(--mn)}.bar-w{flex:1;display:flex;align-items:flex-end;width:100%}.bar-f{width:100%;border-radius:var(--r1) 3px 0 0;min-height:2px}.bar-l{font-size:var(--t-label);color:var(--txM);font-family:var(--mn);text-align:center;line-height:1.1}
.out-card{background:var(--gdD);border:1px solid var(--gdB);border-radius:var(--r2);padding:10px 12px;margin-bottom:5px}.out-hook{font-size:var(--t-body);font-weight:700;margin-bottom:3px}.out-meta{font-size:var(--t-label);color:var(--txM);font-family:var(--mn)}.out-why{font-size:var(--t-label);color:var(--gd);margin-top:3px}
.goals-panel{background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);box-shadow:var(--lift);padding:14px 18px}
.goals-hdr{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.goals-title{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--txM);font-weight:500;display:flex;align-items:center;gap:6px}.goals-title i{width:6px;height:6px;border-radius:50%;background:var(--gn);display:inline-block}
.goals-edit{background:none;border:none;color:var(--txM);cursor:pointer;font-size:var(--t-label);font-family:var(--mn);letter-spacing:.06em;transition:color .15s,transform .12s}.goals-edit:hover{color:var(--gd)}
.goal-row{display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--bd)}.goal-row:last-child{border-bottom:none}
.goal-label{font-size:var(--t-label);color:var(--txS);flex:0 0 140px;display:flex;align-items:center;gap:5px}.goal-label svg{width:10px;height:10px;flex-shrink:0;opacity:.5}
.goal-bar-wrap{flex:1;height:5px;background:var(--bg);border-radius:var(--r1);overflow:hidden;min-width:60px}.goal-bar-fill{height:100%;border-radius:var(--r1);transition:width .5s ease}
.goal-vals{font-family:var(--mn);font-size:var(--t-label);color:var(--txM);white-space:nowrap;min-width:88px;text-align:right}.goal-vals b{color:var(--tx);font-weight:700;font-size:var(--t-body)}
.goal-pct{font-family:var(--mn);font-size:var(--t-label);color:var(--txM);width:36px;text-align:right;flex-shrink:0}
.goal-hit{width:14px;height:14px;border-radius:50%;background:var(--gn);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
.goal-override{width:52px;padding:3px 5px;background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1);color:var(--gd);font-size:var(--t-label);font-family:var(--mn);font-weight:700;text-align:right;outline:none}.goal-override:focus{border-color:var(--gd)}

/* === SETTINGS === */
.trk-list{display:flex;flex-direction:column;gap:4px;margin-top:4px}.trk-item{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1)}
.trk-dot{width:10px;height:10px;border-radius:var(--r1);flex-shrink:0;cursor:pointer;position:relative}.trk-nm{flex:1;font-size:var(--t-label);color:var(--tx);background:none;border:none;font-family:var(--sn);outline:none}.trk-nm:focus{color:var(--gd)}
.trk-rm{background:none;border:none;color:var(--txM);cursor:pointer;font-size:var(--t-label);padding:0 3px;line-height:1;transition:color .15s}.trk-rm:hover{color:var(--rd)}
.trk-add{width:100%;padding:6px;border:1px dashed var(--bd);border-radius:var(--r1);background:none;color:var(--txM);font-size:var(--t-label);cursor:pointer;font-family:var(--mn);letter-spacing:.06em;margin-top:2px;transition:color .15s,border-color .15s}.trk-add:hover{border-color:var(--txS);color:var(--txS)}
.trk-colors{position:absolute;top:14px;left:0;background:var(--sf);border:1px solid var(--bd);border-radius:var(--r1);padding:4px;display:flex;gap:3px;z-index:10;box-shadow:0 4px 12px rgba(0,0,0,.5)}.trk-cp{width:14px;height:14px;border-radius:var(--r1);cursor:pointer;border:1px solid transparent}.trk-cp:hover{border-color:var(--tx)}

/* === PIPELINE === */
.pipe-wrap{padding:var(--pad) var(--pad) 0}
.pipe-hdr{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;flex-wrap:wrap;gap:8px}
.pipe-types{display:flex;gap:4px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r4);padding:3px}
.pipe-type{padding:5px 12px;border-radius:var(--r2);font-size:var(--t-label);font-weight:500;font-family:var(--sn);letter-spacing:0;text-transform:none;cursor:pointer;border:none;background:none;color:var(--txM);transition:color .2s,background-color .2s,transform .2s}
.pipe-type.on{background:#ffffff0f;color:var(--tx)}
.pipe-type:hover:not(.on){color:var(--txS)}
.pipe-cols{display:flex;gap:14px;overflow-x:auto;padding-bottom:40px;min-height:calc(100vh - 160px);min-height:calc(100dvh - 160px);align-items:flex-start}
.pipe-col{flex:0 0 240px;min-width:240px;max-width:240px;display:flex;flex-direction:column;gap:8px;background:#ffffff05;border:1px solid var(--bd);border-radius:var(--r6);padding:10px}
.pipe-col-hdr{display:flex;align-items:center;gap:6px;padding:0 2px 10px;border-bottom:2px solid var(--bd)}
.pipe-col-hdr.s0{border-color:var(--rd)}.pipe-col-hdr.s1{border-color:var(--gd)}.pipe-col-hdr.s2{border-color:var(--bl)}.pipe-col-hdr.s3{border-color:var(--pr)}.pipe-col-hdr.s4{border-color:var(--gn)}.pipe-col-hdr.s5{border-color:var(--tl)}
.pipe-col-t{font-family:var(--mn);font-size:var(--t-label);font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.pipe-col-hdr.s0 .pipe-col-t{color:var(--rd)}.pipe-col-hdr.s1 .pipe-col-t{color:var(--gd)}.pipe-col-hdr.s2 .pipe-col-t{color:var(--bl)}.pipe-col-hdr.s3 .pipe-col-t{color:var(--pr)}.pipe-col-hdr.s4 .pipe-col-t{color:var(--gn)}.pipe-col-hdr.s5 .pipe-col-t{color:var(--tl)}
.pipe-col-ct{font-size:var(--t-label);font-family:var(--mn);color:var(--txM);background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1);padding:1px 5px;font-weight:600}
/* Same fill and edge as .rc. A pipeline card and a reel card are the same
   object; giving the calendar a visible edge and leaving this one invisible
   would have traded one inconsistency for another. */
.pipe-card{background:var(--sf2);border:1px solid var(--edge);border-radius:var(--r4);padding:13px 15px;cursor:pointer;box-shadow:var(--e1);transition:border-color .2s,box-shadow .2s,transform .2s;position:relative}
.pipe-card:hover{border-color:var(--edgeS);transform:translateY(-1px);box-shadow:var(--e2)}.pipe-card.dragging{opacity:.35;transform:scale(.97)}.pipe-card.pipe-card-drop::before{content:'';position:absolute;left:6px;right:6px;top:-6px;height:4px;border-radius:2px;background:var(--gd);box-shadow:0 0 8px rgba(212,175,55,.5)}
.pipe-card-title{font-size:var(--t-body);font-weight:600;line-height:1.45;color:var(--tx);font-family:var(--sn)}
.pipe-card .pipe-card-title{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.pipe-card{min-height:92px}
.pipe-col-t::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:6px;background:currentColor;vertical-align:middle}
.pipe-card-date{font-size:var(--t-label);font-family:var(--mn);color:var(--txM);letter-spacing:.04em;margin-top:4px}
.pipe-card-type{display:inline-block;padding:2px 6px;border-radius:var(--r1);font-size:var(--t-label);font-weight:700;font-family:var(--mn);letter-spacing:.04em;margin-top:6px}
.pipe-card-acts{position:absolute;top:8px;right:8px;display:flex;gap:3px;opacity:0;transition:opacity .15s}
.pipe-card:hover .pipe-card-acts{opacity:1}
.pipe-card-act{background:var(--bg);border:1px solid var(--bd);color:var(--txM);cursor:pointer;font-size:var(--t-label);padding:2px 5px;font-family:var(--mn);border-radius:var(--r1);transition:color .15s,border-color .15s,transform .12s}
.pipe-card-act:hover{color:var(--tx);border-color:var(--bdL)}
.pipe-add{width:100%;padding:8px;border:1px dashed var(--bd);border-radius:var(--r2);background:none;color:var(--txM);font-size:var(--t-label);cursor:pointer;font-family:var(--mn);letter-spacing:.06em;margin-top:2px;transition:color .15s,border-color .15s}
.pipe-add:hover{border-color:var(--txS);color:var(--txS)}
.pipe-card.posted{opacity:.55;padding:8px 12px;min-height:0 !important}
.pipe-card.posted:hover{opacity:.8}
.pipe-card.posted .pipe-card-title{display:block !important;font-size:var(--t-label);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pipe-card.posted .pipe-meta{display:none}
.pipe-card.posted .pipe-card-acts{display:none}
.pipe-card.posted .pipe-tag{display:none}
.pipe-drop-zone{min-height:60px;border:2px dashed transparent;border-radius:var(--r2);transition:border-color .15s,background-color .15s;flex:1;display:flex;flex-direction:column;gap:8px}
.pipe-drop-zone.over{border-color:var(--gd);background:var(--gdD)}
.pipe-drop-zone:empty{align-items:center;justify-content:center}.pipe-drop-zone:empty::before{content:'Nothing here yet';font-size:var(--t-body);color:var(--txM);opacity:.55}
.pipe-meta .pipe-card-date{margin-top:0}
.pipe-meta{display:flex;gap:6px;align-items:center;margin-top:6px;flex-wrap:wrap}
.pipe-tag{font-size:var(--t-label);font-family:var(--mn);padding:2px 6px;border-radius:var(--r1);font-weight:600;letter-spacing:.04em}

.tg-pri{color:var(--rd);background:var(--rd2);font-weight:700;letter-spacing:.04em}
.rc-pri{border-color:rgba(244,119,107,.4);box-shadow:0 0 8px rgba(244,119,107,.08)}
.pipe-card-pri{border-left:3px solid var(--rd) !important}

/* Login */
.login-wrap{display:flex;align-items:center;justify-content:center;min-height:100vh;min-height:100dvh;padding:20px}
.login-box{background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);box-shadow:var(--lift);padding:40px 36px;max-width:360px;width:100%;text-align:center}
.login-box h1{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--gd);margin-bottom:24px}
.login-box .fi{margin-bottom:10px;text-align:center}
.login-box .btn-g{width:100%;padding:10px;font-size:var(--t-label);margin-top:4px}
.login-err{color:var(--rd);font-size:var(--t-body);margin-top:8px}

/* === MODERN PASS === */
.ck-ov{position:fixed;inset:0;z-index:5000;background:rgba(0,0,0,.72);backdrop-filter:blur(6px);display:flex;justify-content:center;align-items:flex-start;padding-top:14vh}
.ck{width:100%;max-width:540px;background:var(--sf);border:1px solid var(--bdL);border-radius:var(--r6);overflow:hidden;box-shadow:0 24px 70px rgba(0,0,0,.65);animation:ckin .15s ease-out}
@keyframes ckin{from{opacity:0;transform:scale(.97) translateY(-6px)}to{opacity:1;transform:none}}
.ck-in{width:100%;padding:15px 18px;background:transparent;border:none;outline:none;color:var(--tx);font-size:var(--t-lead);border-bottom:1px solid var(--bd);font-family:var(--sn)}
.ck-list{max-height:320px;overflow-y:auto;padding:6px}
.ck-it{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:var(--r2);cursor:pointer;font-size:var(--t-body);color:var(--txS)}
.ck-it.on{background:var(--gdD);color:var(--gd4)}
.ck-tag{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.06em;padding:2px 6px;border-radius:var(--r1);background:rgba(255,255,255,.06);flex-shrink:0;min-width:48px;text-align:center}
.ck-it.on .ck-tag{background:rgba(0,0,0,.18)}
.ck-ft{padding:9px 16px;border-top:1px solid var(--bd);font-family:var(--mn);font-size:var(--t-label);letter-spacing:.06em;color:var(--txM)}
.skel{background:linear-gradient(90deg,var(--rs) 25%,#26262c 50%,var(--rs) 75%);background-size:200% 100%;animation:skm 1.2s infinite;border-radius:var(--r4)}
@keyframes skm{from{background-position:200% 0}to{background-position:-200% 0}}
.undo-bar{position:fixed;bottom:52px;left:50%;transform:translateX(-50%);background:var(--rs);border:1px solid var(--bdL);color:var(--tx);padding:9px 10px 9px 16px;border-radius:var(--r2);font-size:var(--t-label);z-index:4000;display:flex;align-items:center;gap:14px;box-shadow:0 8px 24px rgba(0,0,0,.5);animation:fu .25s}
.undo-bar button{background:none;border:none;color:var(--gd);font-family:var(--mn);font-size:var(--t-label);font-weight:700;letter-spacing:.06em;cursor:pointer;padding:4px 8px;border-radius:var(--r2);transition:background-color .15s}
.undo-bar button:hover{background:var(--gdD)}
.posted-sum{border:1px dashed var(--bd);border-radius:var(--r4);padding:16px 12px;text-align:center;cursor:pointer;color:var(--txS);font-size:var(--t-label);transition:border-color .15s}
.posted-sum:hover{border-color:var(--txS)}
.posted-sum b{color:var(--tl);font-size:18px;display:block;margin-bottom:2px}
@keyframes gw{from{width:0}}
.goal-bar-fill{animation:gw .6s ease-out}
.rc-stage i{animation:gw .5s ease-out}
@keyframes nu{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.oi-v{animation:nu .3s ease-out both}
@keyframes vin{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.pipe-wrap,.dsh,.ov-page,.cal-wrap{animation:vin .3s ease-out both}
.wk{animation:vin .3s ease-out both}.wk:nth-child(2){animation-delay:.04s}.wk:nth-child(3){animation-delay:.08s}.wk:nth-child(4){animation-delay:.12s}.wk:nth-child(5){animation-delay:.16s}.wk:nth-child(6){animation-delay:.2s}
.pipe-cols>.pipe-col{animation:vin .3s ease-out both}.pipe-cols>.pipe-col:nth-child(2){animation-delay:.04s}.pipe-cols>.pipe-col:nth-child(3){animation-delay:.08s}.pipe-cols>.pipe-col:nth-child(4){animation-delay:.12s}.pipe-cols>.pipe-col:nth-child(5){animation-delay:.16s}.pipe-cols>.pipe-col:nth-child(6){animation-delay:.2s}
@keyframes fdin{from{opacity:0}}
.ov{animation:fdin .15s ease-out}.ov .mdl{animation:ckin .18s ease-out}.cfm{animation:fdin .12s ease-out}.cfm-b{animation:ckin .15s ease-out}
.btn:active,.pl:active,.pipe-type:active,.tab:active,.plat-tab:active,.sb-item:active,.pipe-card-act:active,.goals-edit:active,.ov-card-act:active{transform:scale(.95)}
@keyframes pop{0%{transform:scale(.4)}60%{transform:scale(1.18)}100%{transform:scale(1)}}
.rc-rec-chip,.goal-hit{animation:pop .25s ease-out}
/* Was a 2s pulse that never stopped. */
.pipe-card.overdue{border-left:3px solid var(--rd);box-shadow:var(--e1),0 0 0 1px rgba(244,119,107,.18)}
.nyt-row{display:flex;align-items:center;gap:10px;padding:10px 8px;border-bottom:1px solid var(--bd);cursor:pointer;border-radius:var(--r1);transition:background .12s}
.nyt-row:hover{background:rgba(255,255,255,.03)}.nyt-row:last-child{border-bottom:none}
.nyt-tag{font-family:var(--mn);font-size:var(--t-label);font-weight:700;letter-spacing:.06em;padding:3px 7px;border-radius:var(--r1);flex-shrink:0;min-width:54px;text-align:center}
/* ONE PAGE BOX FOR EVERY SCREEN. max-width plus auto margins would have
   pulled the top bar's rule and the stats bar's rule in off the window edges
   with it; padding that grows to absorb the overflow keeps those lines running
   the full width while everything a person reads stays inside one column and
   lines up from screen to screen. It also settles the three different top
   paddings the pages used to carry -- 24, 20 and 16 -- which made the content
   jump as you tabbed between them. */
.topbar,.sbar,.ov-page,.dsh,.pipe-wrap,.cal-wrap,.wk-addw{
  padding-inline:max(var(--pad),calc((100% - var(--page))/2))}
/* THE PIPELINE BOARD IS THE ONE SCREEN THAT WANTS THE WHOLE WINDOW. Six fixed
   240px columns need 1510px, so a 1440 page turned a board that used to show
   every stage at once on a wide screen into one that scrolled sideways. The
   cap is set per view rather than removed from .pipe-wrap alone, so this
   screen's top bar moves out with its board and the two stay aligned. */
.main-area.view-pipeline{--page:100%}

@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none !important;transition:none !important}}

/* The min-width:1100px block that used to live here is gone. Everything it did
   -- grid columns, vertical card stacks, the add pill, the top-edge drop bar --
   is now the single base layout, so there is no breakpoint to cross. */
@media(max-width:900px){.sidebar{width:60px}.sb-logo,.sb-sub,.sb-section-t,.sb-item span,.sb-cl span,.sb-user-name,.sb-user-role,.sb-cl-add,.sb-badge{display:none}.sb-item{justify-content:center;padding:10px}.sb-cl{justify-content:center}.main-area{margin-left:60px}:root{--sidebar:60px}.row2{grid-template-columns:1fr}.fr,.fr4{grid-template-columns:1fr}.og{grid-template-columns:1fr 1fr}.goal-label{flex:0 0 100px;font-size:var(--t-label)}}
/* .rc,.addc{min-width:100%} used to live in the rule above. Combined with the
   nowrap flex row it was the whole 641-900px failure: min-width beat the 220px
   flex-basis, so each card became as wide as the week strip and the strip
   scrolled for thousands of pixels. Both the rule and the row are gone. */

.sb-burger{display:none;position:fixed;top:10px;left:10px;z-index:260;width:36px;height:36px;border-radius:var(--r2);background:var(--sf);border:1px solid var(--bdL);color:var(--tx);cursor:pointer;align-items:center;justify-content:center}
.sb-bd{position:fixed;inset:0;z-index:270;background:rgba(0,0,0,.6);backdrop-filter:blur(2px)}

/* === MOBILE (<=640px) === */
@media(max-width:640px){
  .sb-burger{display:flex}
  .sidebar{transform:translateX(-105%);transition:transform .25s ease-out;width:230px;z-index:280;box-shadow:8px 0 30px rgba(0,0,0,.5)}
  .sidebar.open{transform:none}
  :root{--sidebar:0px;--pad:12px}
  .main-area{margin-left:0}
  .sb-logo,.sb-sub,.sb-section-t{display:block}
  .sb-item span,.sb-cl span,.sb-badge{display:inline}
  .sb-user-name,.sb-user-role{display:block}
  .sb-cl-add{display:block}
  .sb-item{justify-content:flex-start;padding:7px 10px}
  .sb-cl{justify-content:flex-start}
  /* THE BARS ACROSS THE TOP TOOK 152px OF A 375px PHONE and 213 of a 320 --
     more than a third of the screen before a single card. Tighter padding and
     a month label that is only as wide as its own text claw most of that back;
     the rest comes from folding a week away, which the header now offers. */
  .topbar{padding:8px 12px 8px 52px;gap:8px;row-gap:6px}
  .topbar-l{gap:8px;row-gap:6px}
  .mo span{min-width:0}
  .ov-page{padding-top:36px}
  .topbar-title{font-size:var(--t-lead)}
  .pipe-hdr{margin-bottom:12px}
  .pipe-col{flex:0 0 82vw;min-width:82vw;max-width:82vw}
  .wk-h-r1{row-gap:6px}

  /* iOS SAFARI ZOOMS THE WHOLE PAGE IN whenever you tap a field whose text is
     under 16px, and it does not zoom back out. Every field in the reel panel
     was 11 to 15px, so editing one hook on a phone left the entire app sitting
     at about 120% until you pinched it back by hand. 16px is not a type
     choice here -- it is the exact threshold that stops the zoom, which is why
     it overrides the handful of fields that set their own size inline. */
  .fi,.ck-in,input,textarea,select{font-size:16px !important}
  .sbar{padding:6px 12px;gap:10px;row-gap:4px}
  .sbar-prog{width:110px}
  .nyt-row{flex-wrap:wrap;row-gap:4px}
  .pace-row{row-gap:6px}
  .pace-name{width:100%}
  .pace-note{flex-basis:100%}
  .goal-row{flex-wrap:wrap;row-gap:4px}
  .goal-label{flex:0 0 100%}
  .card{padding:12px 12px;overflow-x:auto}
  .ov-card{overflow-x:auto}
  .ck-ov{padding-top:8vh}
  .ck{max-width:92vw}
  .mdl{max-width:96vw}
  .mb{padding:12px 12px}
  .og{grid-template-columns:1fr 1fr}
  .ov-strip{grid-template-columns:1fr}
  /* The queue row wraps on a phone, which put its chevron at the LEFT of the
     second line directly under the tag chips, reading as a stray character.
     Pushed to the right of whichever line it lands on, it is an affordance
     again. */
  .nyt-row>span:last-child{margin-left:auto}
}
/* Touch devices: hover-revealed controls must be visible */
@media(hover:none){
  .rc-icons{opacity:1;gap:12px}
  .pipe-card-acts{opacity:1;position:static;justify-content:flex-end;margin-bottom:4px}
  .rc:hover{transform:none;box-shadow:none}
  .pipe-card:hover{transform:none;box-shadow:none}

  /* EVERY TAP TARGET BELOW WAS SMALLER THAN A FINGERTIP. Apple's minimum is
     44x44 and the accessibility floor is 24x24; the filmed toggle and the
     Frame.io link on every card measured 16x16, and the delete-week x was 18.
     The card is 323px wide on a phone, so two 44px controls beside the tags
     fit on the meta row with room to spare -- nothing has to be given up. */
  /* The hit area is 40x40; the box you can SEE stays 28. Painting the full 40
     put two heavy squares on every card and swamped the tags beside them. The
     12px gap is chosen so the two 40px areas meet exactly and neither steals
     taps from the other. */
  .rtg,.drv{position:relative;width:28px;height:28px;border-radius:var(--r3)}
  .rtg svg,.drv svg{width:13px;height:13px}
  .rtg::after,.drv::after{content:'';position:absolute;top:50%;left:50%;width:40px;height:40px;transform:translate(-50%,-50%)}
  /* Same treatment as .rtg and .drv beside it: the box you SEE stays 28 tall,
     the box a thumb has to hit is 40. Without the ::after this was the only
     control on the card missing its hit area, and it is the one that posts. */
  .rc-post{position:relative;height:28px;padding:0 12px;border-radius:var(--r3)}
  .rc-post::after{content:'';position:absolute;top:50%;left:0;right:0;height:40px;transform:translateY(-50%)}
  .wk-fold,.wk-eb{width:44px;height:44px}
  .wk-fold svg{width:14px;height:14px}
  .wk-eb{font-size:var(--t-body)}
  .mx{width:44px;height:44px;margin:-8px -10px -8px 0}
  .mo button{min-width:44px;min-height:44px;font-size:var(--t-body)}
  .btn,.plat-tab,.tab{min-height:40px}
  .mini-btn{min-height:36px;padding:2px 12px}
  .sb-item,.sb-cl,.sb-cl-add{min-height:44px}
  .fi{min-height:44px}
  .pl{min-height:36px;display:inline-flex;align-items:center}
}

/* THE HEADER'S OWN CONTROLS, sized after the touch block above so these win.
   44px is right for the things you hit constantly -- the filmed toggle and the
   link on every card, the fold and delete on every week header. Applying it to
   the page chrome as well cost 36px of permanent header on a phone, because
   the platform tabs and the month arrows sit on two rows that no amount of
   tightening will merge at 375px wide. 40px for those two is still a
   comfortable thumb target and nearly twice the accessibility floor of 24,
   and it hands the height back to the calendar. */
@media(max-width:640px){
  .mo button{min-width:40px;min-height:40px}
  .plat-tab,.tab{min-height:36px}
  .plat-tabs,.tabs{padding:2px}
  .topbar{padding:6px 12px 6px 52px;row-gap:4px}
  .sbar .btn{min-height:36px}

  /* THE REEL PANEL MUST FIT THE SCREEN IT IS ON. Its body was capped at 78% of
     the viewport and its footer sat below that, so on a short phone the row
     holding DEL and CLOSE fell off the bottom and had to be scrolled to. The
     panel is now a column no taller than the screen: the body takes whatever
     is left over and scrolls inside itself, and the buttons are always on. */
  .mdl{display:flex;flex-direction:column;max-height:calc(100dvh - 24px)}
  .mb{max-height:none;flex:1 1 auto;min-height:0}
}

.script-read{font-size:var(--t-lead);line-height:1.75;color:var(--tx);max-width:600px}
.script-cue{font-family:var(--mn);font-size:var(--t-label);letter-spacing:.06em;color:var(--gd);opacity:.8;text-transform:uppercase;margin:9px 0 1px;font-weight:600}
.script-line{margin:0 0 3px;white-space:pre-wrap;word-break:break-word}
.script-empty{color:var(--txM);font-style:italic;font-size:var(--t-body)}
.mini-btn{background:var(--bg);border:1px solid var(--bd);color:var(--txS);font-family:var(--mn);font-size:var(--t-label);letter-spacing:.06em;padding:2px 8px;border-radius:var(--r1);cursor:pointer;transition:color .15s,border-color .15s}
.mini-btn:hover{border-color:var(--bdL);color:var(--tx)}
.fld-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}
.mini-btn:disabled{opacity:.5;cursor:default}

/* Planned thumbnail in the reel modal. The dashed box is the drop target and the
   empty state; once a picture is in, it shows whole on black rather than
   cropped, because this is where someone checks the text on it is readable. */
.thumb-box{position:relative;border:1px dashed var(--bd);border-radius:var(--r3);min-height:92px;display:flex;align-items:center;justify-content:center;transition:border-color .15s,background .15s}
.thumb-box.has{border-style:solid;border-color:var(--bd);background:#000;overflow:hidden}
.thumb-box.drop{border-color:var(--gdB);background:var(--gdD)}
.thumb-empty{font-size:var(--t-body);color:var(--txM);text-align:center;padding:var(--s3)}
.thumb-img{display:block;width:100%;aspect-ratio:16/9;object-fit:contain}
.thumb-img.thumb-wait{background:var(--rs)}
.thumb-img.thumb-gone{display:flex;align-items:center;justify-content:center;font-family:var(--mn);font-size:var(--t-label);letter-spacing:.06em;color:var(--txM)}
.thumb-busy{position:absolute;top:8px;right:8px;font-family:var(--mn);font-size:10px;letter-spacing:.08em;color:var(--gd);background:rgba(0,0,0,.7);padding:2px 6px;border-radius:var(--r1)}
.thumb-err{font-size:var(--t-body);color:var(--rd);margin-top:4px}

/* === REEL MODAL: hierarchy, one selection colour, quiet footer ===
   Field labels step down so the section titles read as chapters. Every
   pill group selects in gold; unselected pills lose their box. */
.mdl .fl{font-size:10px;letter-spacing:.08em;color:var(--txD);margin-bottom:5px}
.mdl .sec{font-size:var(--t-label);letter-spacing:.14em;color:var(--gd4);font-weight:600;margin-top:10px;padding-top:14px;padding-bottom:2px;border-top:1px solid var(--bd)}
.mdl .pg{gap:4px}
.mdl .pl{border-color:transparent;background:var(--rs);color:var(--txM);font-weight:600;padding:4px 9px}
.mdl .pl:hover{color:var(--txS);background:var(--sf2)}
.mdl .pl.on,.mdl .pl.on:hover{background:var(--gd);border-color:var(--gd);color:var(--gdInk)}
.pl-dot{width:5px;height:5px;border-radius:50%;display:inline-block;margin-right:2px}
.mdl .pl.on .pl-dot{outline:1px solid var(--gdInk)}
.mdl .fi{border-color:var(--bd)}
.mh{gap:10px}
.mtabs{margin-left:auto}
.btn-ghost{border-color:transparent}
.btn-ghost:hover{border-color:transparent;background:var(--rs)}
.fr3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px}
.mmenu-wrap{position:relative}
.mmenu{position:absolute;right:0;bottom:calc(100% + 6px);min-width:180px;background:var(--sf2);border:1px solid var(--bdL);border-radius:var(--r4);box-shadow:var(--e4);padding:4px;z-index:10;display:flex;flex-direction:column}
.mmenu-i{text-align:left;background:none;border:none;color:var(--txS);font-family:var(--sn);font-size:var(--t-body);padding:8px 10px;border-radius:var(--r2);cursor:pointer}
.mmenu-i:hover{background:var(--rs);color:var(--tx)}
.mmenu-rd{color:var(--rd)}
@media(max-width:520px){.mh{flex-wrap:wrap}.mtabs{order:3;width:100%;margin-left:0}}

/* Performance numbers as a read-out. Zernio fills most of them in, so the
   default is to show what is there rather than ask for it. */
.num-read{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:8px;padding:2px 0}
.num-cell{background:var(--bg);border:1px solid var(--bd);border-radius:var(--r1);padding:7px 9px;min-width:0}
.num-l{display:block;font-family:var(--mn);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--txD);margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.num-v{display:block;font-family:var(--mn);font-size:15px;font-weight:700;color:var(--txS);font-variant-numeric:tabular-nums}
.num-empty{font-size:var(--t-body);color:var(--txM);padding:4px 0}
.num-note{font-size:11px;color:var(--txD);margin-top:6px;line-height:1.5}
/* Explanatory notes sit below the thing they explain, not beside it in weight. */
.hint{font-size:12px;color:var(--txM);line-height:1.6;margin-bottom:8px;max-width:60ch}
.sec.sec-a{display:flex;align-items:center;justify-content:space-between;gap:8px}
/* Number spinners inside a dialog are decoration: they crowd short fields to
   the point of clipping the value, and every one of these is typed, not nudged.
   Arrow keys still step the value. */
.mdl input[type=number]::-webkit-outer-spin-button,
.mdl input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.mdl input[type=number]{-moz-appearance:textfield;appearance:textfield}
