/* Specialists — the gallery and the profile, drawn INSIDE the Team pane's body.
   Tokens only (work-clay.css). The frame (.osAppSec/.osAppEmpty/.osAppRefuse) is
   the shared one; nothing here redefines it.
   Design: docs/specs/SPEC-SPECIALIST-CHARACTERS-2026-09-08.md §5 — the hero is a
   window the character stands IN FRONT OF, contour on the figure and on the box
   at one weight, the box's contour passing behind the figure where they cross.
   Contrast, measured on the composited clay values rather than assumed
   (2026-09-08): ink on panel 14.2:1 · muted on panel 5.5:1 · ink on the hero's
   deepest violet wash (9%) 12.8:1 · muted on that wash 4.9:1 · ink on the AI
   chip's 14% tint 12.0:1 · amber on panel 5.0:1 · mint on panel 5.0:1.
   ⛔ Under 4.5:1 and therefore NEVER used for normal text: --violet on --panel
   (4.2:1), --onfill on --fill (4.35:1 — buttons carry it as a shared semantic
   token, see DESIGN.md), and --amber on its own 8–10% tint (4.3:1) — so amber
   is a bar, a border, a mark; the words beside it stay --ink. Nothing sits over
   the ground glow (muted on it would be 3.4:1): it pools under the feet only.
   The only literals in this file are the rgba(255,255,255,…) lit top edge that
   --lift itself is made of — a highlight, never a colour. */
.osApp[data-app="team"]{
  /* the one contour, shared by the figure and the box — ink softened toward the
     panel so it reads as a drawn line, the C2 icon family's language */
  --spContour:color-mix(in srgb,var(--ink) 58%,var(--panel));
  --spContourW:1.5px;
}
.osApp[data-app="team"] .spTrust{margin:0 0 14px;font:400 13.5px/1.5 var(--osDisp);color:var(--muted)}
.osApp[data-app="team"] .osAppSec>h3 i{font-style:normal;color:var(--muted);margin-left:4px}
.osApp[data-app="team"] .spQuiet>h3{color:var(--muted)}
/* the roster: room above the first row for the medallions that straddle each card's top edge */
/* rows size independently: a cast does not stand in a line, and a card stretched
   to its tallest neighbour carries a dead band nobody composed */
.osApp[data-app="team"] .spGrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:18px 14px;padding-top:30px;align-items:start}

/* ── the card ─────────────────────────────────────────────────────────────── */
.osApp[data-app="team"] .spCard{display:flex;flex-direction:column;gap:10px;padding:14px 16px 16px;border:1px solid var(--line2);border-radius:var(--r-s);background:var(--panel);box-shadow:var(--lift);min-width:0}
.osApp[data-app="team"] .spCard.standing{background:var(--surf);box-shadow:none}
.osApp[data-app="team"] .spCard.unknown{border-style:dashed;box-shadow:none}
/* the name sits beside the shoulder: bottoms aligned with the medallion */
.osApp[data-app="team"] .spTop{display:flex;align-items:flex-end;gap:12px;min-width:0}
/* THE MEDALLION — the shape .tmAvatar.worker already uses, sized for a portrait,
   carrying the same contour as the profile hero and straddling the card's top
   edge so the card's line passes behind it. Initials are the FALLBACK; the C2
   render replaces them only where the asset exists (rules at the foot).
   ⛔ Pictorial art never reads below ~24px; this is 72 on a card, 132 on the profile. */
.osApp[data-app="team"] .spPortrait{width:72px;height:72px;margin-top:-40px;border-radius:22px;display:grid;place-items:center;flex:none;position:relative;background:color-mix(in srgb,var(--violet) 16%,var(--panel));color:var(--violet);font:700 24px var(--osDisp);letter-spacing:.02em;border:var(--spContourW) solid var(--spContour);box-shadow:inset 0 2px 0 rgba(255,255,255,.7),0 8px 18px color-mix(in srgb,var(--ink) 12%,transparent)}
.osApp[data-app="team"] .spWho{display:flex;flex-direction:column;gap:2px;min-width:0;padding-bottom:2px}
.osApp[data-app="team"] .spWho b{font:700 17px/1.2 var(--osDisp);color:var(--ink);letter-spacing:-.01em;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.osApp[data-app="team"] .spWho small{font:400 13px/1.4 var(--osDisp);color:var(--muted)}
/* ⛔ the permanent AI chip — Art. 50(1). Ink on a violet tint, never white on violet. */
.osApp[data-app="team"] .spAI{display:inline-block;font:700 10px/1 var(--osMono);letter-spacing:.1em;padding:3px 6px;border-radius:var(--r-pill);border:1px solid color-mix(in srgb,var(--violet) 55%,var(--line2));background:color-mix(in srgb,var(--violet) 14%,var(--panel));color:var(--ink);vertical-align:middle}
.osApp[data-app="team"] .spPurpose{margin:0;font:400 14px/1.5 var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spMeta{font:400 11.5px/1.4 var(--osMono);color:var(--muted);letter-spacing:.02em}
.osApp[data-app="team"] .spJobs{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.osApp[data-app="team"] .spJobs li{position:relative;padding-left:14px;font:400 13.5px/1.45 var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spJobs li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:2px;border-radius:2px;background:var(--violet)}
.osApp[data-app="team"] .spJobs.big{gap:8px}
.osApp[data-app="team"] .spJobs.big li{font-size:15.5px;line-height:1.5;padding-left:18px}
.osApp[data-app="team"] .spJobs.big li::before{width:9px;top:.7em}
.osApp[data-app="team"] .spTools{display:flex;gap:6px;flex-wrap:wrap}
.osApp[data-app="team"] .spTool{font:500 11.5px/1 var(--osMono);padding:5px 9px;border-radius:var(--r-pill);border:1px solid color-mix(in srgb,var(--violet) 55%,var(--line2));background:color-mix(in srgb,var(--violet) 10%,transparent);color:var(--ink)}
/* a declared_not_served lane is present and honest: outlined, dashed, quiet — never omitted */
.osApp[data-app="team"] .spTool.not{border:1px dashed var(--line2);background:transparent;color:var(--muted);text-decoration:line-through;text-decoration-color:var(--line2);cursor:help}
.osApp[data-app="team"] .spBoundary{margin:0;padding-left:10px;border-left:2px solid var(--line2);font:400 13px/1.5 var(--osDisp);color:var(--muted)}
.osApp[data-app="team"] .spNote{margin:0;font:400 11.5px/1.45 var(--osMono);color:var(--muted)}
.osApp[data-app="team"] .spStanding{margin:0;font:400 12.5px/1.45 var(--osDisp);color:var(--muted)}
.osApp[data-app="team"] .spFoot{margin-top:auto;display:flex;flex-direction:column;gap:8px;padding-top:6px}

/* ── presses ──────────────────────────────────────────────────────────────── */
.osApp[data-app="team"] .spPrimary,.osApp[data-app="team"] .spBtn{min-height:44px;padding:10px 18px;border-radius:var(--r-pill);font:600 13.5px var(--osDisp);cursor:pointer;border:1px solid var(--line2)}
.osApp[data-app="team"] .spPrimary{background:var(--fill);color:var(--onfill);border-color:var(--fill);align-self:flex-start;box-shadow:0 6px 16px color-mix(in srgb,var(--violet) 28%,transparent)}
.osApp[data-app="team"] .spPrimary:hover{filter:brightness(1.06)}
.osApp[data-app="team"] .spBtn{background:var(--surf);color:var(--ink)}
.osApp[data-app="team"] .spBtn:hover{background:var(--surf2)}
.osApp[data-app="team"] .spBtn.amber{border-color:var(--amber);color:var(--amber);background:var(--panel)}
.osApp[data-app="team"] .spPrimary.sm,.osApp[data-app="team"] .spBtn.sm{min-height:36px;padding:7px 13px;font-size:12.5px}
.osApp[data-app="team"] .spPrimary.sm{box-shadow:none}
.osApp[data-app="team"] .spPrimary[disabled],.osApp[data-app="team"] .spBtn[disabled]{opacity:.5;cursor:wait}
.osApp[data-app="team"] .spActs{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.osApp[data-app="team"] .spLink{background:none;border:0;padding:2px 4px;font:500 11.5px var(--osMono);color:var(--ink);text-decoration:underline;cursor:pointer}
.osApp[data-app="team"] .spHired{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:var(--surf);color:var(--ink);cursor:pointer;font:inherit;min-height:44px}
.osApp[data-app="team"] .spHired:hover{background:var(--surf2);border-color:var(--line2)}
.osApp[data-app="team"] .spHiredTx{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.osApp[data-app="team"] .spHiredTx b{font:600 14px/1.3 var(--osDisp);display:flex;align-items:center;gap:6px}
.osApp[data-app="team"] .spHiredTx small{font:400 11.5px/1.45 var(--osMono);color:var(--muted)}
.osApp[data-app="team"] .spGo{color:var(--muted);font-size:18px;flex:none}
.osApp[data-app="team"] .spBadge{font:600 10.5px/1 var(--osMono);padding:4px 8px;border-radius:var(--r-pill);border:1px solid var(--line2);color:var(--ink);white-space:nowrap}
/* ⛔ amber text on an amber tint is 4.3:1 — the badge keeps ink words, amber edge and wash */
.osApp[data-app="team"] .spBadge.amber{border-color:var(--amber);color:var(--ink);background:color-mix(in srgb,var(--amber) 10%,var(--panel))}
/* forms: the hire name, an instruction edit, a rejection reason, the cap */
.osApp[data-app="team"] .spHireForm,.osApp[data-app="team"] .spEdit,.osApp[data-app="team"] .spReject,.osApp[data-app="team"] .spConfirm,.osApp[data-app="team"] .spCap{display:flex;flex-direction:column;gap:8px}
.osApp[data-app="team"] .spHireForm label,.osApp[data-app="team"] .spReject label,.osApp[data-app="team"] .spConfirm label,.osApp[data-app="team"] .spCap label{display:flex;flex-direction:column;gap:4px;font:400 12px var(--osDisp);color:var(--muted)}
.osApp[data-app="team"] .spCap{flex-direction:row;align-items:flex-end;flex-wrap:wrap}
.osApp[data-app="team"] .spCap input{width:80px}
.osApp[data-app="team"] input[type="text"],.osApp[data-app="team"] input:not([type]),.osApp[data-app="team"] input[type="number"],.osApp[data-app="team"] textarea{font:400 14px/1.45 var(--osDisp);color:var(--ink);background:var(--panel);border:1px solid var(--line2);border-radius:10px;padding:9px 12px;min-height:44px;width:100%;box-sizing:border-box}
.osApp[data-app="team"] textarea{resize:vertical}
.osApp[data-app="team"] input:focus,.osApp[data-app="team"] textarea:focus{outline:2px solid var(--violet);outline-offset:1px}

/* ── the profile — a dossier on a colleague ───────────────────────────────── */
.osApp[data-app="team"] .spBack{border:1px solid var(--line);border-radius:var(--r-pill);padding:8px 14px;min-height:36px;background:var(--surf);color:var(--muted);cursor:pointer;font:500 12.5px var(--osDisp);margin:0 0 18px;position:relative;z-index:3}
.osApp[data-app="team"] .spBack:hover{color:var(--ink);border-color:var(--line2)}
/* section rhythm inside the dossier: the frame's rule becomes a tab-line that runs
   from the heading to the right edge, and sections breathe wider than a list */
.osApp[data-app="team"] .spProfile .osAppSec{border-top:0;margin-top:30px;padding-top:0}
.osApp[data-app="team"] .spProfile .osAppSec>h3{display:flex;align-items:center;gap:12px;margin:0 0 14px;font:600 11.5px var(--osMono);letter-spacing:.09em;color:var(--muted)}
.osApp[data-app="team"] .spProfile .osAppSec>h3::after{content:"";flex:1;height:1px;background:var(--line2);min-width:24px}
.osApp[data-app="team"] .spProfile .osAppSec>h3 i{margin-left:0;color:var(--faint)}

/* THE HERO. Without a full-body render: the portrait tile sits large in the
   top-left corner, bleeding past the header's edge (the gallery spec's corner). */
.osApp[data-app="team"] .spHead{position:relative;margin:22px 0 4px 16px;padding:22px 24px 22px 140px;border:var(--spContourW) solid var(--spContour);border-radius:var(--r);background:var(--panel);box-shadow:var(--lift);min-height:120px}
.osApp[data-app="team"] .spPortrait.big{position:absolute;left:-16px;top:-18px;margin:0;width:132px;height:132px;border-radius:34px;font-size:44px;box-shadow:inset 0 3px 0 rgba(255,255,255,.75),0 12px 26px color-mix(in srgb,var(--ink) 14%,transparent)}
/* WITH a character — the box is a window the character stands in front of.
   overflow:visible on purpose (§5): the figure breaks the top and the right
   edge, head above the panel, feet just below it. The hero's own top and right
   margins hold the overhang, so the Team card (overflow:hidden) never clips it.
   The 256 tile is hidden: one face on the hero, not two. */
/* ⛔ NO LINE MAY CROSS THE CHARACTER (owner, 2026-09-09: "cut out issues,
   that's not cool"). The renders themselves measure clean — alpha 0 all
   round the ring, no magenta fringe from the key — but the panel's own
   1.5px contour ran BEHIND her across the chest and down the leg, and a
   drawn line meeting a drawn figure reads as a bad cut whichever one is on
   top. So the panel now ENDS before she starts: a reserved column on the
   right holds her, the wash leans toward her so the two read as one scene,
   and her contour is the only line in that column. */
.osApp[data-app="team"] .spHead.hasCharacter{overflow:visible;margin:84px 300px 78px 0;padding:24px 28px;min-height:0;isolation:isolate;
  background:
    radial-gradient(62% 84% at 84% 62%,color-mix(in srgb,var(--violet) 15%,var(--panel)) 0%,transparent 66%),
    linear-gradient(135deg,var(--panel) 0%,var(--panel) 52%,color-mix(in srgb,var(--violet) 9%,var(--panel)) 100%)}
.osApp[data-app="team"] .spHead.hasCharacter .spPortrait.big{display:none}
.osApp[data-app="team"] .spHead.hasCharacter .spHeadTx{position:relative;z-index:2}
/* the figure: sized by height. The hero is as tall as its words (name, role,
   purpose, brain, plinth — measured 355px with a two-line purpose), so a 480px
   figure clears the panel top by ~70px and its shoes stand ~56px BELOW the
   bottom edge, on the page, over the glow. The hero's 84px top margin plus the
   back button's row hold the head inside the Team card, which clips.
   The contour is four 1.5px drop-shadows in the shared contour colour (the same
   weight as the box's border), then one soft ink shadow that seats the figure
   in front of the panel.
   ⛔ `right` is per render, because the renders are not cut alike: Jānis's
   640×960 source keeps ~25% margin either side of the figure, Anna's and Ilze's
   are cropped to the silhouette. Each rule puts the figure's right edge ~30px
   past the panel — add a line per cast member, measured, never guessed. */
.osApp[data-app="team"] .spFullBody{position:absolute;right:-250px;bottom:-56px;height:480px;width:auto;z-index:1;pointer-events:none;user-select:none;
  filter:drop-shadow(var(--spContourW) 0 0 var(--spContour)) drop-shadow(calc(var(--spContourW) * -1) 0 0 var(--spContour)) drop-shadow(0 var(--spContourW) 0 var(--spContour)) drop-shadow(0 calc(var(--spContourW) * -1) 0 var(--spContour)) drop-shadow(0 18px 22px color-mix(in srgb,var(--ink) 18%,transparent))}
/* the ground glow pools under the shoes ON THE PAGE, outside the panel's bottom
   edge — violet only, no text ever sits on it */
.osApp[data-app="team"] .spFullBody[data-art="sp-company-analyst"]{right:-292px}
.osApp[data-app="team"] .spHead.hasCharacter::after{content:"";position:absolute;right:-278px;bottom:-74px;width:230px;height:40px;border-radius:50%;z-index:0;pointer-events:none;background:radial-gradient(closest-side,color-mix(in srgb,var(--violet) 34%,transparent),color-mix(in srgb,var(--violet) 12%,transparent) 55%,transparent)}
.osApp[data-app="team"] .spHeadTx{display:flex;flex-direction:column;gap:8px;min-width:0}
.osApp[data-app="team"] .spHeadTx h2{margin:0;font:800 27px/1.15 var(--osDisp);color:var(--ink);letter-spacing:-.018em;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.osApp[data-app="team"] .spHeadTx h2 .spAI{font-size:10.5px;padding:4px 7px}
.osApp[data-app="team"] .spRole{font:600 11.5px/1.4 var(--osMono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.osApp[data-app="team"] .spRole .spMono{text-transform:none;letter-spacing:.02em}
.osApp[data-app="team"] .spHeadTx p{margin:6px 0 0;font:400 15.5px/1.55 var(--osDisp);color:var(--ink);max-width:56ch}
.osApp[data-app="team"] .spBrain{margin-top:4px;font:400 11.5px/1.5 var(--osMono);color:var(--muted);max-width:56ch}
.osApp[data-app="team"] .spMono{font:400 11.5px var(--osMono);color:var(--muted);word-break:break-all}
.osApp[data-app="team"] .spReach{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-direction:column;gap:7px}
.osApp[data-app="team"] .spReach li{display:flex;align-items:baseline;gap:10px;font:400 14px/1.45 var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spReach li b{font:500 12.5px var(--osMono);padding:3px 9px;border-radius:var(--r-pill);border:1px solid color-mix(in srgb,var(--violet) 55%,var(--line2));background:color-mix(in srgb,var(--violet) 10%,transparent)}
.osApp[data-app="team"] .spReach li.served span::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--mint);margin-right:7px;vertical-align:1px}
.osApp[data-app="team"] .spReach li.not b{border:1px dashed var(--line2);background:transparent;color:var(--muted);text-decoration:line-through;text-decoration-color:var(--line2)}
.osApp[data-app="team"] .spReach li.not span{color:var(--muted)}
/* THE PLINTH — what the colleague stands on, at the foot of the hero beside the
   figure: the jurisdiction/languages line and the boundary, set like a clause —
   ink bar, quiet label. It is what fills the hero's lower half with meaning
   instead of leaving the figure beside a blank. */
.osApp[data-app="team"] .spPlinth{display:flex;flex-direction:column;gap:10px;margin-top:14px;padding-top:14px;border-top:1px solid var(--line);max-width:56ch}
.osApp[data-app="team"] .spPlinthMeta{font:600 11px/1.4 var(--osMono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.osApp[data-app="team"] .spBoundaryBox{margin:0;padding:12px 14px;border:1px solid var(--line);border-left:3px solid var(--ink);border-radius:0 var(--r-s) var(--r-s) 0;background:var(--surf);font:400 14px/1.5 var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spBoundaryBox span{display:block;font:600 10.5px var(--osMono);letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin-bottom:4px}
.osApp[data-app="team"] .spSub{margin:18px 0 10px;font:600 13px var(--osDisp);color:var(--ink);display:flex;align-items:center;gap:8px}
.osApp[data-app="team"] .spSub:first-of-type{margin-top:0}
.osApp[data-app="team"] .spSub i{font-style:normal;font:500 11px var(--osMono);color:var(--muted);min-width:20px;height:20px;padding:0 6px;border-radius:var(--r-pill);background:var(--surf2);display:inline-grid;place-items:center}
.osApp[data-app="team"] .spList{display:flex;flex-direction:column;gap:10px}

/* an instruction block and a lesson share one anatomy: head line, body, foot */
.osApp[data-app="team"] .spBlock,.osApp[data-app="team"] .spLesson{display:flex;flex-direction:column;gap:9px;padding:14px 16px;border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel);box-shadow:inset 0 1px 0 rgba(255,255,255,.8)}
.osApp[data-app="team"] .spBlock header,.osApp[data-app="team"] .spLesson header{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.osApp[data-app="team"] .spLesson header small{font:400 11.5px/1.4 var(--osMono);color:var(--muted);margin-left:auto}
/* the ordinal is a dossier number: a small tile, tabular, so a list of twelve lines up */
.osApp[data-app="team"] .spOrd{font:600 11px/1 var(--osMono);font-variant-numeric:tabular-nums;color:var(--muted);min-width:24px;height:22px;padding:0 6px;border-radius:7px;background:var(--surf2);display:inline-grid;place-items:center}
.osApp[data-app="team"] .spOrd:empty{display:none}
.osApp[data-app="team"] .spKind{font:500 10.5px/1 var(--osMono);letter-spacing:.06em;text-transform:uppercase;padding:5px 8px;border-radius:var(--r-pill);background:var(--surf2);color:var(--ink)}
/* THE SOURCE BADGES — three provenances, each with its own FORM as well as its
   colour, so they survive a monochrome print and a colour-blind reader:
   catalogue = a hollow square (shipped, immutable) · person = a filled mint dot
   (a hand wrote it) · lesson = a violet ring (it grew on its own). Ink words always. */
.osApp[data-app="team"] .spSrc{display:inline-flex;align-items:center;gap:6px;font:500 11px/1 var(--osMono);padding:4px 9px 4px 7px;border-radius:var(--r-pill);border:1px solid var(--line2);color:var(--muted);background:var(--panel)}
.osApp[data-app="team"] .spSrc::before{content:"";width:7px;height:7px;flex:none;border:1.5px solid currentColor;border-radius:2px;box-sizing:border-box}
.osApp[data-app="team"] .spSrc.person{border-color:var(--mint);color:var(--ink);background:color-mix(in srgb,var(--mint) 10%,var(--panel))}
.osApp[data-app="team"] .spSrc.person::before{border:0;border-radius:50%;background:var(--mint)}
.osApp[data-app="team"] .spSrc.lesson{border-color:color-mix(in srgb,var(--violet) 60%,var(--line2));color:var(--ink);background:color-mix(in srgb,var(--violet) 11%,var(--panel))}
.osApp[data-app="team"] .spSrc.lesson::before{width:9px;height:9px;border:2px solid var(--violet);border-radius:50%;background:color-mix(in srgb,var(--violet) 30%,var(--panel))}
.osApp[data-app="team"] .spDate{font:400 11px/1 var(--osMono);color:var(--muted)}
.osApp[data-app="team"] .spDate.expired{color:var(--amber)}
.osApp[data-app="team"] .spBody{margin:0;font:400 14.5px/1.55 var(--osDisp);color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere}
.osApp[data-app="team"] .spWhy{margin:0;font:400 13px/1.5 var(--osDisp);color:var(--muted)}
.osApp[data-app="team"] .spBlock.off{background:var(--surf);box-shadow:none}
.osApp[data-app="team"] .spBlock.off .spBody{color:var(--muted)}
/* expired: struck through and dated, with the words beside it — not hidden */
.osApp[data-app="team"] .spBlock.expired .spBody{text-decoration:line-through;text-decoration-color:var(--line2);color:var(--muted)}
.osApp[data-app="team"] .spBlock footer,.osApp[data-app="team"] .spLesson footer{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;padding-top:4px}
.osApp[data-app="team"] .spBlock footer small{font:400 11.5px/1.45 var(--osMono);color:var(--muted)}
.osApp[data-app="team"] .spEv{font:400 11.5px/1.45 var(--osMono);color:var(--muted)}
/* THE CANDIDATE — the decision the person came here to make, so it is the most
   alive card on the page: violet contour at the shared weight, a faint violet
   wash, a lifted violet shadow, the proposed change set larger. */
.osApp[data-app="team"] .spLesson.candidate{border:var(--spContourW) solid color-mix(in srgb,var(--violet) 62%,var(--line2));background:color-mix(in srgb,var(--violet) 5%,var(--panel));box-shadow:inset 0 1px 0 rgba(255,255,255,.8),0 14px 34px color-mix(in srgb,var(--violet) 16%,transparent);padding:16px 18px;gap:11px}
.osApp[data-app="team"] .spLesson.candidate .spKind{background:color-mix(in srgb,var(--violet) 16%,var(--panel));color:var(--ink)}
.osApp[data-app="team"] .spLesson.candidate .spBody{font-size:16px;line-height:1.5}
.osApp[data-app="team"] .spLesson.candidate .spBody b{font-weight:600}
.osApp[data-app="team"] .spLesson.candidate footer{border-top:1px solid color-mix(in srgb,var(--violet) 22%,var(--line));padding-top:12px;margin-top:2px}
/* ⛔ never a silent dot: an unacknowledged lesson has an amber edge, a badge and a press */
.osApp[data-app="team"] .spLesson.unread{border-color:var(--amber);border-left-width:3px}
/* THE UNTRUSTED BAND — a genuine warning, not a tint: amber bar, amber edge, a
   mark, and ink words (amber words on an amber wash fail 4.5:1) */
.osApp[data-app="team"] .spBand{padding:10px 12px;border-radius:8px;font:400 13px/1.5 var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spBand.amber{display:flex;align-items:flex-start;gap:10px;padding:11px 14px 11px 12px;border:1px solid color-mix(in srgb,var(--amber) 45%,var(--line2));border-left:4px solid var(--amber);border-radius:0 8px 8px 0;background:color-mix(in srgb,var(--amber) 9%,var(--panel));font-weight:500}
.osApp[data-app="team"] .spBand.amber::before{content:"!";flex:none;width:18px;height:18px;border-radius:50%;background:var(--amber);color:var(--panel);font:800 12px/18px var(--osMono);text-align:center;margin-top:1px}
.osApp[data-app="team"] .spFold{margin-top:14px}
.osApp[data-app="team"] .spFold>summary{cursor:pointer;font:500 12.5px var(--osDisp);color:var(--muted);padding:8px 0;min-height:36px}
.osApp[data-app="team"] .spFold>summary:hover{color:var(--ink)}
.osApp[data-app="team"] .spFold>.spList{padding-top:6px}
.osApp[data-app="team"] .spFold .spLesson{background:var(--surf);box-shadow:none}

/* the learning switch: pills, the sentence that says what the current mode means, the confirm */
.osApp[data-app="team"] .spPills{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.osApp[data-app="team"] .spPill{min-height:40px;padding:8px 16px;border-radius:var(--r-pill);border:1px solid var(--line2);background:transparent;color:var(--muted);font:500 13px var(--osDisp);cursor:pointer}
.osApp[data-app="team"] .spPill.on{background:var(--ink);border-color:var(--ink);color:var(--panel)}
.osApp[data-app="team"] .spConfirm{margin-top:12px;padding:14px 16px;border:1px solid var(--amber);border-left:4px solid var(--amber);border-radius:0 var(--r-s) var(--r-s) 0;background:color-mix(in srgb,var(--amber) 7%,var(--panel))}
.osApp[data-app="team"] .spConfirm b{font:600 14px var(--osDisp);color:var(--ink)}
.osApp[data-app="team"] .spConfirm p{margin:0;font:400 13.5px/1.5 var(--osDisp);color:var(--ink);max-width:62ch}
.osApp[data-app="team"] .spConfirm input{width:96px}
.osApp[data-app="team"] .spConfirm label small{font:400 11px/1.4 var(--osMono);color:var(--muted)}
.osApp[data-app="team"] .spCap{margin-top:10px}

/* ── motion, narrow columns ───────────────────────────────────────────────── */
/* ⛔ no float, no parallax (§5.6) — the figure arrives once and then stands still */
@media (prefers-reduced-motion:no-preference){
  .osApp[data-app="team"] .spCard{transition:box-shadow .18s ease,transform .18s ease}
  .osApp[data-app="team"] .spCard:not(.standing):not(.unknown):hover{box-shadow:var(--lift-2);transform:translateY(-1px)}
  .osApp[data-app="team"] .spFullBody{animation:spArrive .5s cubic-bezier(.2,.7,.2,1) both}
  .osApp[data-app="team"] .spLesson.candidate{transition:box-shadow .18s ease}
  @keyframes spArrive{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
}
/* ⛔ a figure breaking a box at 375px just clips (§5.7): the character stacks,
   inside the panel, and the contour language carries the composition alone */
@media (max-width:560px){
  .osApp[data-app="team"] .spGrid{grid-template-columns:1fr}
  .osApp[data-app="team"] .spHead{margin:0;padding:16px;display:flex;flex-direction:column;gap:12px}
  .osApp[data-app="team"] .spHead.hasCharacter{margin:0 0 8px;padding:18px 16px 0;min-height:0;background:linear-gradient(180deg,var(--panel) 0%,var(--panel) 60%,color-mix(in srgb,var(--violet) 9%,var(--panel)) 100%)}
  .osApp[data-app="team"] .spHead.hasCharacter::after{right:auto;left:50%;transform:translateX(-50%);bottom:-14px;width:200px;height:28px}
  .osApp[data-app="team"] .spPortrait.big{position:static;width:96px;height:96px;border-radius:26px;font-size:32px}
  .osApp[data-app="team"] .spFullBody{position:static;display:block;align-self:center;width:auto;height:320px;max-width:100%;order:3;margin:10px 0 0;right:auto;bottom:auto}
  .osApp[data-app="team"] .spHeadTx h2{font-size:24px}
  .osApp[data-app="team"] .spBlock footer,.osApp[data-app="team"] .spLesson footer{flex-direction:column;align-items:flex-start}
  .osApp[data-app="team"] .spLesson header small{margin-left:0;width:100%}
}

/* ⛔ ONLY THE CAST IS ATTACHED. Measured on the rendered gallery 2026-09-08:
   with the four remaining OBJECT icons still bound, Toms sat between Anna and
   Ilze as a server tower among three faces — and one icon in a row of portraits
   does not read as "not cast yet", it reads as a broken card. Initials are the
   honest third state and they look deliberate; a mixed row does not.
   ⚡ Add a role here the same day its character is forged, never before.

   ── THE PORTRAITS, ATTACHED ONLY WHERE THE ASSET EXISTS ────────────────────
   ⛔ ONE RULE PER FORGED ASSET, AND THAT IS THE DEGRADATION MECHANISM, not an
   omission. portrait() always renders the clay tile with the role's initials;
   a rule below paints the character render over it and turns the letters
   transparent. A role whose portrait has not been forged simply has no rule,
   so it keeps its initials — there is no broken <img>, no missing-asset icon
   and no placeholder photograph anywhere in the fallback path.
   ⛔ Add a line here ONLY after the render has passed icon-family-check.py at
   256x256. A rule pointing at a file that is not on disk paints nothing and
   leaves the letters transparent — an empty tile, which is worse than initials.
   ⚡ The 256 bust is cut flat at three edges by design, so it is drawn to COVER
      the medallion and clipped by its radius — it never breaks the tile; only
      the full-body render breaks the box, and only on the profile. */
.osApp[data-app="team"] .spPortrait[data-art="sp-accountant"],
.osApp[data-app="team"] .spPortrait[data-art="sp-lawyer"],
.osApp[data-app="team"] .spPortrait[data-art="sp-cto"],
.osApp[data-app="team"] .spPortrait[data-art="sp-financial-advisor"],
.osApp[data-app="team"] .spPortrait[data-art="sp-sales-lead"],
.osApp[data-app="team"] .spPortrait[data-art="sp-operations-lead"],
.osApp[data-app="team"] .spPortrait[data-art="sp-company-analyst"]{
  color:transparent;
  background-repeat:no-repeat;
  background-position:center bottom;
  background-size:cover;
  background-color:color-mix(in srgb,var(--violet) 16%,var(--panel));
}
.osApp[data-app="team"] .spPortrait[data-art="sp-accountant"]{background-image:url(/art/os/sp-accountant.png)}
.osApp[data-app="team"] .spPortrait[data-art="sp-lawyer"]{background-image:url(/art/os/sp-lawyer.png)}
.osApp[data-app="team"] .spPortrait[data-art="sp-cto"]{background-image:url(/art/os/sp-cto.png)}
.osApp[data-app="team"] .spPortrait[data-art="sp-financial-advisor"]{background-image:url(/art/os/sp-financial-advisor.png)}
.osApp[data-app="team"] .spPortrait[data-art="sp-sales-lead"]{background-image:url(/art/os/sp-sales-lead.png)}
.osApp[data-app="team"] .spPortrait[data-art="sp-company-analyst"]{background-image:url(/art/os/sp-company-analyst.png)}
/* ⚡ operations-lead was drawn on 2026-09-08 and never added to this cast
   list, so a hired operations lead wore initials while her portrait sat on
   disk. The list IS the mechanism; a forgotten line is a silent downgrade. */
.osApp[data-app="team"] .spPortrait[data-art="sp-operations-lead"]{background-image:url(/art/os/sp-operations-lead.png)}

/* ── v0.3 (owner, 2026-09-09): the scene, the door, the icons, the poses ───── */
/* THE SCENE — the trade's desk, keyed, no people, sitting on a violet wash at
   the card's top. It bleeds to the card's edges (the card's padding is undone
   with negative margins) so the medallion straddles the scene's bottom edge
   exactly as it straddled the card's top. Only a role in SCENES gets one. */
.osApp[data-app="team"] .spHeadBtn{display:block;width:100%;margin:0;padding:0;border:0;background:none;text-align:left;font:inherit;color:inherit;cursor:pointer;border-radius:inherit}
.osApp[data-app="team"] div.spHeadBtn{cursor:default}
.osApp[data-app="team"] button.spHeadBtn:focus-visible{outline:2px solid var(--violet);outline-offset:3px;border-radius:var(--r-s)}
.osApp[data-app="team"] .spHeadBtn .spTop{padding-right:4px}
.osApp[data-app="team"] .spHeadBtn .spGo{margin-left:auto;align-self:center;font:600 20px/1 var(--osDisp);color:var(--faint);transition:color .18s,transform .18s}
.osApp[data-app="team"] button.spHeadBtn:hover .spGo{color:var(--violet);transform:translateX(2px)}
.osApp[data-app="team"] button.spHeadBtn:hover .spWho b{color:var(--violet)}
.osApp[data-app="team"] .spCard.hasScene{padding-top:0}
.osApp[data-app="team"] .spScene{display:block;height:118px;margin:0 -16px 0;border-radius:var(--r-s) var(--r-s) 0 0;position:relative;overflow:hidden;
  background:
    radial-gradient(70% 90% at 78% 70%,color-mix(in srgb,var(--violet) 18%,var(--panel)) 0%,transparent 70%),
    linear-gradient(160deg,color-mix(in srgb,var(--violet) 6%,var(--panel)) 0%,color-mix(in srgb,var(--violet) 13%,var(--panel)) 100%);
  border-bottom:1px solid var(--line)}
.osApp[data-app="team"] .spScene::after{content:"";position:absolute;inset:0;background-repeat:no-repeat;background-position:center 58%;background-size:cover;
  filter:drop-shadow(0 6px 10px color-mix(in srgb,var(--ink) 14%,transparent))}
.osApp[data-app="team"] .spScene[data-art="sp-accountant"]::after{background-image:url(/art/os/sp-accountant-scene.png)}
.osApp[data-app="team"] .spScene[data-art="sp-financial-advisor"]::after{background-image:url(/art/os/sp-financial-advisor-scene.png)}
.osApp[data-app="team"] .spScene[data-art="sp-lawyer"]::after{background-image:url(/art/os/sp-lawyer-scene.png)}
.osApp[data-app="team"] .spScene[data-art="sp-sales-lead"]::after{background-image:url(/art/os/sp-sales-lead-scene.png)}
.osApp[data-app="team"] .spScene[data-art="sp-cto"]::after{background-image:url(/art/os/sp-cto-scene.png)}
.osApp[data-app="team"] .spScene[data-art="sp-company-analyst"]::after{background-image:url(/art/os/sp-company-analyst-scene.png)}
/* the medallion over the scene keeps its overlap; the scene's wash already
   separates it from the card's ground */
.osApp[data-app="team"] .spCard.hasScene .spPortrait{margin-top:-40px}
/* THE TOOLS AS THE APPS' OWN ICONS — a tile per app, name under the picture,
   the not-yet-served lane greyed and dashed, never omitted. 34px pictorial:
   above the ~24px floor. */
/* ⚡ ONE ROW, ICONS ONLY (owner, 2026-09-09: "smaller icons … max one row").
   The name is in `title`/`aria-label` and printed in full on the profile; a
   26px pictorial icon is above the ~24px floor the design file sets, and the
   row cannot wrap — the overflow becomes a `+N` chip that NAMES the rest. */
.osApp[data-app="team"] .spTools{gap:6px;flex-wrap:nowrap;align-items:center}
.osApp[data-app="team"] .spTool.icon{display:inline-grid;place-items:center;width:38px;height:38px;padding:0;border-radius:11px;
  border:1px solid var(--line);background:var(--surf);flex:none}
.osApp[data-app="team"] .spTool.icon img{width:26px;height:26px;display:block;filter:drop-shadow(0 2px 3px color-mix(in srgb,var(--ink) 12%,transparent))}
.osApp[data-app="team"] .spTool.icon.not{border-style:dashed;background:transparent}
.osApp[data-app="team"] .spTool.icon.not img{opacity:.42;filter:grayscale(1)}
/* the overflow chip: a count you can hover, never a silent truncation */
.osApp[data-app="team"] .spTool.more{display:inline-grid;place-items:center;height:38px;min-width:34px;padding:0 9px;border-radius:11px;flex:none;
  border:1px dashed var(--line2);background:transparent;color:var(--muted);font:600 12px/1 var(--osMono);cursor:help}
.osApp[data-app="team"] .spReach li{align-items:center}
.osApp[data-app="team"] .spReach li img{width:28px;height:28px;flex:none;filter:drop-shadow(0 2px 3px color-mix(in srgb,var(--ink) 12%,transparent))}
.osApp[data-app="team"] .spReach li.not img{opacity:.42;filter:grayscale(1)}
.osApp[data-app="team"] .spReach li b{font:600 14px/1.3 var(--osDisp);padding:0;border:0;background:none}
.osApp[data-app="team"] .spReach li.not b{text-decoration:line-through;text-decoration-color:var(--line2);color:var(--muted);border:0;background:none}
/* THE ROLE PROFILE's hire door, in the hero beside the figure */
.osApp[data-app="team"] .spHireBox{margin-top:14px;display:flex;flex-direction:column;gap:10px;align-items:flex-start}
.osApp[data-app="team"] .spHiredAs{display:flex;flex-direction:column;gap:6px;width:100%;max-width:420px}
.osApp[data-app="team"] .spHiredAs small{font:600 10.5px/1 var(--osMono);letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
.osApp[data-app="team"] .spNotHired{margin:6px 0 0}
/* THE POSES — the character at work, a strip of full-height renders with the
   same contour as the hero's figure, captions in a whisper. Scrolls sideways
   on a narrow pane rather than wrapping into a second, smaller row. */
.osApp[data-app="team"] .spPoses{display:flex;gap:18px;overflow-x:auto;padding:14px 8px 18px;scroll-snap-type:x proximity;
  border-radius:var(--r);background:linear-gradient(180deg,transparent 0%,transparent 62%,color-mix(in srgb,var(--violet) 9%,transparent) 100%)}
.osApp[data-app="team"] .spPose{flex:none;margin:0;display:flex;flex-direction:column;align-items:center;gap:8px;scroll-snap-align:start}
.osApp[data-app="team"] .spPose img{height:240px;width:auto;display:block;
  filter:drop-shadow(var(--spContourW) 0 0 var(--spContour)) drop-shadow(calc(var(--spContourW) * -1) 0 0 var(--spContour)) drop-shadow(0 var(--spContourW) 0 var(--spContour)) drop-shadow(0 calc(var(--spContourW) * -1) 0 var(--spContour)) drop-shadow(0 14px 16px color-mix(in srgb,var(--ink) 16%,transparent))}
.osApp[data-app="team"] .spPose figcaption{font:500 11px/1 var(--osMono);letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
@media (max-width:720px){
  .osApp[data-app="team"] .spScene{height:100px;margin:0 -16px 0}
  .osApp[data-app="team"] .spScene::after{background-size:cover;background-position:center 58%}
  .osApp[data-app="team"] .spPose img{height:200px}
}
