/* 5.0 - the world.

   The navigation model is the company itself. Five levels, one isometric
   plate, seen from one angle: company, department, process, person, skill.
   You click the thing, not a word for the thing.

   Two rules from the handoff are load-bearing and easy to lose:

     Colour encodes state, never taxonomy. A SPARK domain is not "the blue
     one". A process that has been described is green whether it is a floor
     tile seen from above, a figure seen from the front, a rail dot or a row
     in a list. An earlier pass gave each domain its own hue and the world
     became unreadable: five taxonomy hues fighting three state colours.

     An action is a tinted card with a filled button. A fact is flat with no
     background until hover. They never mix, because when both were styled
     alike nothing on the screen told you what to do.

   This file also retints 4.0's tokens. The twenty four workflow screens are
   4.0's and are mounted unchanged inside overlay sheets, so they have to read
   as part of this world rather than as a window onto another one. Overriding
   the custom properties is the whole mechanism: spren4.css loads first and
   defines them, this file loads second and redefines them. */

:root{
  /* ---------- ink and ground ---------- */
  --ground:#07061A;
  --surface:#0B0A1F;
  --raised:rgba(16,14,44,.99);
  --panel:rgba(10,9,32,.72);
  --panel-soft:rgba(10,9,32,.6);
  --chrome:rgba(13,11,38,.94);

  --ink:#F2F1FA;
  --ink78:rgba(242,241,250,.78);
  --ink66:rgba(242,241,250,.66);
  /* The contrast floor. Several passes of this design drifted under it. */
  --ink62:rgba(242,241,250,.62);
  --hairline:rgba(242,241,250,.1);
  --border:rgba(242,241,250,.16);
  --border2:rgba(242,241,250,.18);

  /* ---------- state, and only state ---------- */
  --done:#4FD1A5;      /* described and agreed. Spren has their words. */
  --gold:#E3B457;      /* booked, live, or a file that cleared the line */
  --invited:#8B98F0;   /* asked and incomplete. Also anything clickable. */
  --none:rgba(242,241,250,.30);   /* nobody has described this */
  --broken:#FF8A73;    /* a contradiction, a gap, too weak to automate */
  --action:#4F46E5;
  --action-tint:rgba(67,56,202,.2);
  --action-tint-hi:rgba(67,56,202,.42);
  --lit:#FFF0C9;       /* light thrown by an opened crate */

  --link:#C7CCFA;
  --filemark:#D97757;
  --avatar:#4338CA;

  --sans:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI',sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;

  /* ---------- 4.0's tokens, retinted ----------
     Same names, world values, so a 4.0 screen mounted in a sheet inherits
     this palette without a line of it being rewritten. */
  --page:var(--surface);
  --side:var(--panel);
  --card:rgba(16,14,44,.86);
  --raise:rgba(20,18,52,.9);
  --over:var(--raised);
  --sunk:rgba(7,6,26,.7);
  --chip:rgba(242,241,250,.08);
  --line:var(--hairline);
  --line2:rgba(242,241,250,.07);
  --edge:var(--border);
  --rule:var(--border2);
  --ghost:var(--none);
  --ink2:var(--ink78);
  --ink3:var(--ink66);
  --dim:var(--ink62);
  --mute:var(--ink62);
  --brand:var(--action);
  --brand2:var(--invited);
  --good:var(--done);
  --warn:var(--gold);
  --bad:var(--broken);
  --bad-ink:var(--broken);
  --bad-wash:rgba(255,138,115,.13);
  --bad-fill:#C7343A;
  --sys:var(--invited);
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--sans);font-size:13px;line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
button{font:inherit;color:inherit;cursor:pointer}
mark{background:rgba(227,180,87,.28);color:var(--lit);border-radius:2px}

/* Every number that can change. Digits must not jitter as they update. */
.num,.stat,.score,.gauge b,.tile b{font-variant-numeric:tabular-nums}

/* The prototypes relied on hover and click. Keyboard gets a real ring. */
:focus-visible{outline:2px solid var(--invited);outline-offset:2px;border-radius:4px}

.vis-hidden{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* ============================================================
   Shell
   ============================================================ */
#shell{
  display:grid;height:100vh;
  grid-template-rows:54px 1fr;
  /* v6 has no inspector. The rail comes back only where v6 draws nothing:
     the portfolio, and one person picked out on the board. */
  grid-template-columns:236px 1fr;
  grid-template-areas:"head head" "tree stage";
  /* Two columns need less room than three. The floor only rises to 1152
     where the rail is actually shown; holding it there everywhere pushed the
     board past the right edge of a zoomed or laptop-sized window. */
  min-width:760px;
  background:var(--surface);
}
#head{
  grid-area:head;display:flex;align-items:center;gap:11px;padding:0 16px;
  background:var(--chrome);border-bottom:1px solid var(--hairline);
}
#tree{
  grid-area:tree;overflow-y:auto;padding:13px 9px 22px;
  background:var(--panel);border-right:1px solid var(--hairline);
}
/* The world is a dark room with lit things in it, and the room needs a floor
   of light to sit on. Without this wash the plate floats on flat black and
   every glow on it has nothing to read against. */
#stage{
  grid-area:stage;position:relative;overflow:hidden;
  background:radial-gradient(120% 90% at 50% 40%,#151240 0%,#0B0A1F 64%,#07061A 100%);
}
#shell.withrail{min-width:1152px;grid-template-columns:236px 1fr 356px;grid-template-areas:"head head head" "tree stage rail"}
#shell:not(.withrail) #rail{display:none}
#rail{
  grid-area:rail;overflow-y:auto;padding:16px 16px 26px;
  background:var(--panel);border-left:1px solid var(--hairline);
}

.wordmark{
  font-size:15px;font-weight:300;letter-spacing:5px;
  text-transform:lowercase;color:var(--ink);
}
.headctx{color:var(--ink62);font-size:12px}
.headright{margin-left:auto;display:flex;align-items:center;gap:9px}

.switcher{
  display:flex;align-items:center;gap:7px;height:30px;padding:0 9px;
  background:transparent;border:1px solid var(--border);border-radius:8px;
  color:var(--ink);font-size:13px;font-weight:600;
}
.switcher:hover{background:rgba(242,241,250,.05)}
.switcher .sq{
  width:16px;height:16px;border-radius:4px;background:var(--avatar);
  display:grid;place-items:center;font-size:9px;font-weight:700;color:#fff;
}

/* The role toggle is real. Leader hides billing behind a panel and replaces
   the invitation action with "invitations are handled for you". */
.seg{display:flex;background:rgba(242,241,250,.06);border-radius:8px;padding:2px}
.seg button{
  height:26px;padding:0 11px;border:0;background:transparent;border-radius:6px;
  font-size:12px;font-weight:600;color:var(--ink62);
}
.seg button[aria-pressed="true"]{background:var(--action-tint-hi);color:var(--ink)}

.kbd{
  font:11px/1 var(--mono);padding:3px 5px;border-radius:5px;
  background:rgba(242,241,250,.08);color:var(--ink62);
}

/* ============================================================
   The tree
   ============================================================ */
.treerow{
  display:flex;align-items:center;gap:9px;width:100%;
  padding:7px 9px;border:0;background:transparent;border-radius:8px;
  color:var(--ink78);font-size:13px;text-align:left;
}
.treerow:hover{background:rgba(242,241,250,.05);color:var(--ink)}
.treerow[aria-current="true"]{background:var(--action-tint-hi);color:var(--ink);font-weight:600}
.treerow .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.treerow .cnt{font-size:11.5px;color:var(--ink62);font-variant-numeric:tabular-nums}

/* An 8px rounded square whose opacity is coverage: nothing described is a
   red outline rather than a dim fill, because dim reads as "a bit". */
.cov{width:8px;height:8px;border-radius:2px;background:var(--done);flex:none}
.cov.zero{background:transparent;border:1px solid var(--broken)}

.procrow{padding-left:26px}
.procrow .pd{width:5px;height:5px;border-radius:2px;flex:none}
.pd.done{background:var(--done)} .pd.part{background:var(--invited)}
.pd.needs{background:var(--broken)} .pd.none{background:var(--none)}

.treesec{
  padding:16px 9px 5px;font-size:10.5px;font-weight:700;letter-spacing:1.6px;
  text-transform:uppercase;color:var(--ink62);
}

/* ============================================================
   The stage
   ============================================================ */
.crumbs{
  position:absolute;top:18px;left:22px;z-index:9;
  display:flex;align-items:center;gap:7px;flex-wrap:wrap;
  /* Clear of the Spren chip, which is pinned to the other corner and is the
     one thing on the stage that must never be covered. */
  /* The two corners share the stage's top edge and must not meet: the
     insets are 22 each side, so the widths have to leave room for both. */
  max-width:46%;
}
.crumb{
  height:26px;padding:0 9px;border-radius:7px;font-size:12px;font-weight:600;
  background:rgba(242,241,250,.06);border:1px solid transparent;color:var(--ink78);
}
.crumb:hover{color:var(--ink)}
.crumb[aria-current="page"]{
  background:var(--action-tint-hi);border-color:var(--invited);color:var(--ink);
}
.depth{display:flex;align-items:center;gap:4px;margin-left:5px}
.depth i{height:5px;width:5px;border-radius:99px;background:var(--none);transition:width .2s ease}
.depth i.seen{background:var(--invited)}
.depth i.now{width:14px;background:var(--invited)}
.depthlbl{font-size:11px;color:var(--ink62);margin-left:5px}

/* Spren, top right, when she is actually in a call. */
/* A pill, not a card: the reference keeps it on one line so it reads as a
   status rather than as a second inspector. */
.sylchip{
  position:absolute;top:18px;right:22px;z-index:9;
  display:flex;align-items:center;gap:9px;padding:6px 8px 6px 11px;
  background:rgba(18,16,48,.94);border:1px solid rgba(227,180,87,.5);border-radius:999px;
}
/* The chip grows with the process name, and a long one walked over the
   breadcrumb. It caps itself rather than pushing the crumbs around. */
.sylchip{max-width:min(40%,480px)}
.sylchip .t{font-size:13px;font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
.sylchip .s{font-size:12px;color:var(--ink66);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;flex:0 1 auto;min-width:40px}
.sylchip .sylring,.sylchip .sylbtn{flex:none}
.sylbtn{
  font-size:11.5px;font-weight:700;padding:4px 9px;border-radius:6px;
  border:1px solid rgba(227,180,87,.6);background:transparent;color:var(--gold);
}
.sylbtn:hover{background:rgba(227,180,87,.14)}
.dot9{width:9px;height:9px;border-radius:50%;flex:none;
  background:var(--invited);box-shadow:0 0 0 4px rgba(139,152,240,.16)}
/* Spren's own face, the 64px asset the handoff ships, not the wordmark glyph.
   An img rather than a background so the ring can be a sibling: a pseudo
   element on a replaced element has nothing to hang off. */
.sylav{
  width:26px;height:26px;border-radius:99px;flex:none;object-fit:cover;
  border:1px solid rgba(227,180,87,.7);background:var(--avatar);
}
.sylring{position:relative;width:26px;height:26px;flex:none}
.sylring::after{
  content:"";position:absolute;inset:-4px;border-radius:99px;pointer-events:none;
  border:1px solid rgba(227,180,87,.55);animation:sylpulse 1.8s ease-in-out infinite;
}

/* One legend for the whole product. If the picture needs a different key on
   every screen, the picture is not a system. */
.legend{
  position:absolute;bottom:22px;left:22px;z-index:8;
  background:var(--panel-soft);border:1px solid var(--hairline);
  border-radius:10px;padding:9px 11px;backdrop-filter:blur(6px);
}
.legend .row{display:flex;align-items:center;gap:13px;flex-wrap:wrap}
.legend .k{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--ink66)}
.legend .sw{width:9px;height:9px;border-radius:2px}
.legend .cap{margin-top:5px;font-size:11px;color:var(--ink62);max-width:420px}

/* ---------- the projection ----------
   One transform, applied once, on one element. The scale is derived from the
   plate's span, which is why the diamond fills the stage identically at every
   level without a single per-level tuning value. */
/* No perspective. The handoff specifies none, and orthographic is what makes
   the nameplate projection in world5.js exact rather than approximate. */
.anchor{position:absolute;left:50%;top:50%;width:0;height:0}
.plate{
  position:absolute;transform-style:preserve-3d;
  transform:rotateX(58deg) rotateZ(-45deg) scale(var(--s,1));
  transition:transform .45s cubic-bezier(.4,0,.2,1);
}
.floor{
  position:absolute;inset:0;border-radius:4px;
  background:rgba(139,152,240,.05);border:1px solid rgba(242,241,250,.16);
}

/* Walls, roof off. Back and left are lit, front and right near-invisible so
   they do not occlude what is behind them.

   The sign matters and is easy to get backwards: with the pivot on the near
   edge the body extends along local +y, and rotateX(90deg) is what carries
   that into +z. At -90 the wall sinks under the floor, which reads as a
   slightly odd shadow rather than as an obvious bug. */
.wall{position:absolute;transform-style:preserve-3d}
.wall.back{transform-origin:top;transform:rotateX(90deg);
  background:linear-gradient(rgba(139,152,240,.24),rgba(139,152,240,.03));
  border-top:1px solid rgba(199,204,250,.42)}
.wall.left{transform-origin:left;transform:rotateY(-90deg);
  background:linear-gradient(90deg,rgba(139,152,240,.24),rgba(139,152,240,.03));
  border-left:1px solid rgba(199,204,250,.42)}
.wall.front{transform-origin:top;transform:rotateX(90deg);
  background:rgba(139,152,240,.055);border-bottom:1px solid rgba(199,204,250,.16)}
.wall.right{transform-origin:left;transform:rotateY(-90deg);
  background:rgba(139,152,240,.055);border-right:1px solid rgba(199,204,250,.16)}

/* A room is a floor plate sized by its mass, not by its name. */
.room{
  position:absolute;border-radius:4px;transform-style:preserve-3d;
  background:rgba(139,152,240,.07);border:1px solid rgba(199,204,250,.3);
  transition:background .18s ease,border-color .18s ease;
}
.room:hover{background:rgba(139,152,240,.18);border-color:var(--invited)}
.room.live{border-color:var(--gold);background:rgba(227,180,87,.1)}
.room.on{border-color:var(--invited);background:rgba(139,152,240,.16)}

/* One square per activity, sorted so lit ones cluster. Countable beats a
   glow: nobody can read a glow, but anybody can see seven dark squares. */
/* A lit tile keeps its border in its own colour rather than going
   transparent. Transparent shrinks the visual box by 2px, and an uneven grid
   is fatal for the one thing whose whole job is being countable. */
.tile{position:absolute;border-radius:3px;background:rgba(242,241,250,.05);border:1px solid rgba(242,241,250,.18)}
/* One square, one person. The four states are the legend's four, and a lit
   square keeps its border in its own colour so every square is the same
   size: an uneven grid is fatal for the one thing whose job is to be
   counted. */
.tile.done,.tile.heard{background:var(--done);border-color:var(--done);box-shadow:0 0 11px -2px var(--done)}
.tile.booked{background:var(--gold);border-color:var(--gold);box-shadow:0 0 11px -2px var(--gold)}
.tile.part,.tile.invited{background:var(--invited);border-color:var(--invited);box-shadow:0 0 11px -2px var(--invited)}
.tile.needs{background:var(--broken);border-color:var(--broken);box-shadow:0 0 11px -2px var(--broken)}

/* What did not fit, stated rather than shrunk into illegibility. It lies in
   the floor with its room, so it takes the same counter-rotation a nameplate
   would: flat on the plate it is as unreadable as the specks it replaces. */
.more{
  position:absolute;font-size:11px;font-weight:700;color:var(--ink62);
  font-variant-numeric:tabular-nums;white-space:nowrap;
  transform-origin:0 0;
  transform:translateZ(2px) rotateZ(45deg) scaleY(1.887);
}

/* ============================================================
   The city. One building per customer, standing on a plot.

   Height is storeys, and a storey is activities, so the skyline is the
   portfolio: a tall building is a big account. Colour is state, as
   everywhere else, and face brightness is the light direction, so the same
   ratio the crates use applies here.
   ============================================================ */
.plot{position:absolute;transform-style:preserve-3d;cursor:pointer}
.plot .pad{
  position:absolute;inset:-9px;border-radius:5px;
  background:rgba(139,152,240,.06);border:1px solid rgba(199,204,250,.16);
  transition:background .18s ease,border-color .18s ease;
}
.plot:hover .pad{background:rgba(139,152,240,.18);border-color:var(--invited)}

.plot .tower{position:absolute;inset:0;transform-style:preserve-3d}
.plot .roof{position:absolute;inset:0;border-radius:2px;border:1px solid rgba(255,255,255,.4)}
.plot .face{
  position:absolute;border:1px solid rgba(255,255,255,.16);
  /* Storey lines. Height is activities, so the storeys are countable for the
     same reason the floor tiles are, and texture does not compete with the
     colour that carries state. */
  background-image:repeating-linear-gradient(rgba(7,6,26,.34) 0 1px,transparent 1px 12px);
}
/* rotateX(90deg), not -90. The pivot is the face's top edge and the body
   extends down it in local y, so -90 sends the wall below the floor and the
   building hangs off the plot instead of standing on it. Same for the side
   face about its left edge. */
.plot .face.f1{left:0;top:100%;width:100%;transform-origin:top;transform:rotateX(90deg);
  filter:brightness(.5)}
.plot .face.f2{left:100%;top:0;height:100%;transform-origin:left;transform:rotateY(-90deg);
  filter:brightness(.72)}

.plot.done .roof,.plot.done .face{background:var(--done)}
.plot.part .roof,.plot.part .face{background:var(--invited)}
.plot.needs .roof,.plot.needs .face{background:var(--broken)}
.plot.none .roof,.plot.none .face{background:rgba(242,241,250,.22)}
.plot.gold .roof,.plot.gold .face{background:var(--gold)}
/* Somebody is talking right now, so the building is lit from inside. */
.plot.gold .roof{box-shadow:0 0 24px 4px rgba(227,180,87,.5)}
.plot.needs .roof{box-shadow:0 0 20px -2px rgba(255,138,115,.45)}

/* Searching does not rebuild the skyline, it darkens what does not match, so
   the city you were reading stays the city in front of you. */
.plot.dim{opacity:.16;filter:saturate(.2)}
.lbl.dim{opacity:0}
.plot.dim,.lbl.dim{transition:opacity .18s ease}

.citychip{
  display:flex;align-items:center;gap:6px;max-width:150px;
  padding:4px 8px;border-radius:7px;white-space:nowrap;
  background:rgba(9,8,26,.92);border:1px solid var(--border2);
  box-shadow:0 12px 26px -12px rgba(0,0,0,.95);
}
.citychip .nm{
  font-size:12px;font-weight:600;overflow:hidden;text-overflow:ellipsis;
}
.citychip .dot{width:7px;height:7px;border-radius:2px;flex:none}
.citychip.done .dot{background:var(--done)}
.citychip.part .dot{background:var(--invited)}
.citychip.needs .dot{background:var(--broken)}
.citychip.none .dot{background:rgba(242,241,250,.3)}
.citychip.gold{border-color:rgba(227,180,87,.6)}
.citychip.gold .dot{background:var(--gold);box-shadow:0 0 8px var(--gold)}

.citysearch{
  position:absolute;left:16px;top:52px;z-index:6;
  display:flex;align-items:center;gap:8px;height:34px;padding:0 11px;
  background:var(--chrome);border:1px solid var(--border);border-radius:9px;
  color:var(--ink62);
}
.citysearch input{
  width:190px;border:0;background:transparent;color:var(--ink);
  font:13px var(--sans);outline:none;
}
.citysearch input::placeholder{color:var(--ink62)}
.citysearch .hits{font-size:11.5px;color:var(--ink62);font-variant-numeric:tabular-nums}

/* ---------- counter-rotation ----------
   1.887 is 1/cos(58deg). The rotateZ undoes the plate's -45deg and the scaleY
   undoes the foreshortening, so something lies in the floor plane and still
   renders 1:1 with the screen. Genuinely crisp, not merely small.

   The figures use this. Nameplates do not: see world5.js on why they are
   projected into the flat layer below instead. */
.decal{
  position:absolute;transform-origin:50% 50%;
  transform:translateZ(var(--z,1px)) rotateZ(45deg) scaleY(1.887);
  pointer-events:none;
}

/* The nameplate layer. Flat, above the plate, positioned by solving the same
   projection in JS, so a plate never sorts against the model in 3D and a
   nameplate is never buried under the room in front of it. */
.labels{position:absolute;inset:0;pointer-events:none;z-index:3}
.labels .lbl{position:absolute;transform:translateY(-6px)}
.plaque{
  min-width:128px;padding:7px 9px;border-radius:8px;
  background:var(--chrome);border:1px solid var(--border);
  box-shadow:0 12px 26px -12px rgba(0,0,0,.95);text-align:left;
}
.plaque .nm{font-size:12.5px;font-weight:600}
.plaque .ct{font-size:11.5px;font-variant-numeric:tabular-nums}
.plaque .pr{font-size:11px;color:var(--ink62);margin-top:2px;max-width:170px}
.plaque.live{border-color:var(--gold)}

/* A figure stands up out of the floor, pivoting at the feet, so it is
   vertical in screen space while its shadow stays on the floor. */
/* 26 by 52. At half that a figure reads as a dot and the idea that people
   stand at the work they described goes with it. The clip-path is what makes
   shoulders rather than a pill, and the halo is the shadow that keeps the
   figure standing on the floor rather than hovering over it. */
.fig{
  position:absolute;width:26px;height:52px;transform-origin:50% 100%;
  transform:rotateZ(45deg) rotateX(-58deg);
}
.fig .head{
  position:absolute;left:50%;top:0;width:13px;height:13px;margin-left:-6.5px;
  border-radius:50%;
}
.fig .body{
  position:absolute;left:50%;top:15px;width:20px;height:30px;margin-left:-10px;
  border-radius:9px 9px 4px 4px;
  clip-path:polygon(28% 0,72% 0,100% 34%,88% 100%,12% 100%,0 34%);
}
.fig .halo{
  position:absolute;left:50%;bottom:-5px;width:21px;height:6px;margin-left:-10.5px;
  border-radius:50%;opacity:.32;filter:blur(2px);
}
.fig.done .head,.fig.done .body,.fig.done .halo,
.fig.heard .head,.fig.heard .body,.fig.heard .halo{background:var(--done)}
.fig.booked .head,.fig.booked .body,.fig.booked .halo{background:var(--gold)}
.fig.part .head,.fig.part .body,.fig.part .halo,
.fig.invited .head,.fig.invited .body,.fig.invited .halo{background:var(--invited)}
.fig.needs .head,.fig.needs .body,.fig.needs .halo{background:var(--broken)}
.fig.none .head,.fig.none .body,.fig.none .halo{background:var(--none)}
.fig.done .head,.fig.heard .head{box-shadow:0 0 10px 2px #4FD1A544}
.fig.booked .head{box-shadow:0 0 10px 2px #E3B45744}
.fig.part .head,.fig.invited .head{box-shadow:0 0 10px 2px #8B98F044}
.fig.needs .head{box-shadow:0 0 10px 2px #FF8A7344}

/* An extruded solid is three faces, and face brightness is what reads as
   light direction. Keep the ratio. */

/* A bay is one process. Dashed when nobody has described it, red when it is
   too weak to automate. */
.bay{
  position:absolute;border-radius:4px;transform-style:preserve-3d;
  background:rgba(139,152,240,.1);border:1px solid rgba(199,204,250,.34);
  transition:background .18s ease,border-color .18s ease;
}
/* .12 against a .11 resting state was no feedback at all. */
.bay:hover{background:rgba(139,152,240,.2);border-color:var(--invited)}
.bay.empty{border-style:dashed;border-color:rgba(242,241,250,.2);background:rgba(139,152,240,.035)}
.bay.weak{border-color:var(--broken)}
.bay.on{border-color:var(--invited);background:rgba(139,152,240,.15)}

/* The steps of a process, top to bottom, in the order they happen. */
.step{
  position:absolute;border-radius:4px;transform-style:preserve-3d;
  background:rgba(139,152,240,.12);border:1px solid rgba(199,204,250,.3);
}
.rail2{position:absolute;width:2px;
  background:linear-gradient(rgba(139,152,240,.6),rgba(139,152,240,.2))}

/* The crate. An opened one is a light source, and everything around it
   responds to that: the card, the border, the ground shadow, the wash. */
.crate{position:absolute;transform-style:preserve-3d}
.crate .lid{
  position:absolute;transform-origin:top;border-radius:3px;
  background:linear-gradient(135deg,#4a3c14,#2a2208);
  border:1px solid rgba(227,180,87,.5);
  animation:lidopen .75s cubic-bezier(.3,1.35,.4,1) both;
}
.crate .inner{
  position:absolute;border-radius:3px;
  background:linear-gradient(135deg,#4a3c14,#2a2208);
  box-shadow:inset 0 0 18px -4px var(--lit);
}
/* A flat fill is not a light source. */
.crate .glow{
  position:absolute;border-radius:3px;
  background:radial-gradient(var(--lit),rgba(227,180,87,.4) 70%);
  box-shadow:0 0 34px 12px rgba(255,240,201,.75);
  animation:halo 2.6s ease-in-out infinite;
}
.crate .shut{
  position:absolute;inset:0;border-radius:3px;
  border:1px solid var(--broken);background:rgba(255,138,115,.1);
}
.crate .shut.locked{border-style:dashed;border-color:var(--none);background:transparent}
/* Shut on purpose, and saying so with a shape rather than only a colour. */
.crate .seal{
  position:absolute;left:0;right:0;height:8px;
  background:repeating-linear-gradient(90deg,var(--broken) 0 7px,rgba(11,10,31,.6) 7px 14px);
}
/* Screen space, so "up" is up. Brightest at the crate and fading out above
   it, which is the direction light actually travels here. */
.beam{
  position:absolute;left:0;bottom:8px;width:44px;height:130px;
  transform-origin:50% 100%;
  background:linear-gradient(rgba(255,240,201,0),rgba(255,240,201,.5));
  filter:blur(5px);
  animation:beam 1.1s ease-out .35s both;pointer-events:none;
}
.mote{
  position:absolute;width:3px;height:3px;border-radius:50%;background:var(--lit);
  box-shadow:0 0 6px 2px rgba(255,240,201,.8);
  animation:motes 2.4s ease-out infinite;pointer-events:none;
}

/* ============================================================
   The inspector rail. Fixed order, and the order is the argument.
   ============================================================ */
.kicker{
  font-size:10.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--ink62);
}
.railhead h1{font-size:21px;font-weight:600;letter-spacing:-.4px;margin:5px 0 5px}
.railhead p{margin:0;color:var(--ink66);font-size:12.5px;line-height:1.45}
.badge{
  display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 7px;
  border-radius:5px;font-size:11px;font-weight:700;
  background:rgba(242,241,250,.08);color:var(--ink78);
}
.badge.done{background:rgba(79,209,165,.16);color:var(--done)}
.badge.gold{background:rgba(227,180,87,.16);color:var(--gold)}
.badge.needs{background:rgba(255,138,115,.16);color:var(--broken)}
.badge.part{background:rgba(139,152,240,.16);color:var(--invited)}

.tiles{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:13px 0}
.tile2{padding:9px 11px;border-radius:10px;background:rgba(242,241,250,.05);border:1px solid var(--hairline)}
.tile2 b{display:block;font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}
.tile2 span{font-size:11px;color:var(--ink62)}

/* An action. Tinted ground, gradient wash, filled button. Never a fact. */
.donext{
  margin:16px 0;padding:13px;border-radius:12px;
  background:linear-gradient(160deg,var(--action-tint-hi),var(--action-tint));
  border:1px solid rgba(139,152,240,.3);
}
.donext .kicker{color:var(--link)}
.donext p{margin:5px 0 11px;font-size:13px;line-height:1.45}

/* A fact. Flat, no background until hover. Never an action. */
.facts{display:flex;flex-direction:column;gap:1px;margin-top:9px}
.fact{
  display:flex;align-items:center;gap:9px;width:100%;padding:9px 7px;
  border:0;background:transparent;border-radius:8px;text-align:left;
  color:var(--ink78);font-size:12.5px;
}
.fact:hover{background:rgba(242,241,250,.05);color:var(--ink)}
.fact .k{flex:1}
.fact .v{color:var(--ink62);font-variant-numeric:tabular-nums}
.fact .chev{color:var(--ink62)}
.fact[disabled]{opacity:1;cursor:default}
.fact[disabled]:hover{background:transparent;color:var(--ink78)}

.btn5{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:32px;padding:0 13px;border-radius:9px;border:1px solid var(--border);
  background:transparent;color:var(--ink);font-size:12.5px;font-weight:600;
}
.btn5:hover{background:rgba(242,241,250,.06)}
.btn5.primary{background:var(--action);border-color:transparent;color:#fff}
.btn5.primary:hover{background:#5a51ea}
.btn5.gold{background:var(--gold);border-color:transparent;color:#2a2208}
.btn5.gold.ok{background:var(--done)}
.btn5[disabled]{opacity:.45;cursor:not-allowed}

/* A gauge, with a gold tick at the line a file has to clear. */
/* The fill carries its band colour and its glow inline, because the band is
   the reading: gold past the line, red where it is too weak to build on. */
.gauge{position:relative;height:6px;border-radius:99px;background:rgba(242,241,250,.14);overflow:visible}
.gauge i{position:absolute;inset:0 auto 0 0;border-radius:99px;background:var(--invited)}
.gauge .tick{
  position:absolute;top:-4px;bottom:-4px;width:2px;
  background:var(--gold);box-shadow:0 0 6px var(--gold);
}

/* ============================================================
   Overlay sheets. The 4.0 screens are mounted in here.
   ============================================================ */
.scrim{
  position:fixed;inset:0;z-index:40;background:rgba(7,6,26,.72);
  display:grid;place-items:center;padding:34px 22px;
}
/* The world behind a sheet. `~` cannot reach back to the shell, because the
   scrim is appended after it, so this asks the body instead. */
body:has(.scrim) #stage{filter:blur(2px) brightness(.5)}
.sheet{
  width:min(680px,100%);max-height:100%;overflow:auto;
  background:var(--raised);border:1px solid var(--border);border-radius:16px;
  box-shadow:0 44px 100px -30px rgba(0,0,0,.95);
  animation:sheetin .22s ease both;
}
/* A workflow screen needs the room a panel does not. */
.sheet.wide{width:min(1180px,100%)}
.sheethead{
  position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:11px;
  padding:16px 18px;background:var(--raised);border-bottom:1px solid var(--hairline);
}
.sheethead h2{flex:1;margin:0;font-size:17px;font-weight:700}
.sheetbody{padding:16px 18px 22px}
/* 4.0's screens bring their own page padding and their own scroller. */
.sheetbody .body,.sheetbody #body{padding:0;overflow:visible;height:auto}

/* ============================================================
   Motion
   ============================================================ */
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes sheetin{from{opacity:0;transform:translateY(12px) scale(.985)}to{opacity:1;transform:none}}
@keyframes land{from{opacity:0;transform:translateX(14px)}to{opacity:1;transform:none}}
/* 114, not -114. Same sign trap as the walls and the city: negative throws
   the lid down through the crate instead of back off it, and the box reads as
   a flat gold smear rather than as something that has been opened. */
@keyframes lidopen{from{transform:rotateX(0)}to{transform:rotateX(114deg)}}
/* The store's lid is a slab hinged on the back edge: the chain walks to the
   hinge, rotates, then walks back, so the lid's own faces can stay centred
   like every other face. --a is how far ajar, and 0 means shut. */
@keyframes cratelid{from{transform:translateY(var(--hy)) translateZ(var(--h)) rotateX(0deg) translateY(var(--hb))}
  to{transform:translateY(var(--hy)) translateZ(var(--h)) rotateX(var(--a,-104deg)) translateY(var(--hb))}}

/* Anticipation is a state, not a transition into one: a sealed crate strains
   against its lid, and the click makes it shake before the lid leaves. */
@keyframes strain{0%,70%,100%{transform:rotateX(56deg) rotateZ(-45deg) translateZ(0)}
  74%{transform:rotateX(56deg) rotateZ(-45deg) translateZ(4px)}
  78%{transform:rotateX(56deg) rotateZ(-48deg) translateZ(1px)}
  82%{transform:rotateX(56deg) rotateZ(-42deg) translateZ(3px)}
  86%{transform:rotateX(56deg) rotateZ(-46deg) translateZ(0)}
  90%{transform:rotateX(56deg) rotateZ(-45deg) translateZ(1px)}}
@keyframes shake{0%{transform:rotateX(56deg) rotateZ(-45deg)}
  12%{transform:rotateX(56deg) rotateZ(-52deg) translateZ(2px)}
  24%{transform:rotateX(56deg) rotateZ(-38deg) translateZ(4px)}
  36%{transform:rotateX(56deg) rotateZ(-51deg) translateZ(2px)}
  48%{transform:rotateX(56deg) rotateZ(-39deg) translateZ(5px)}
  60%{transform:rotateX(56deg) rotateZ(-49deg) translateZ(3px)}
  72%{transform:rotateX(56deg) rotateZ(-41deg) translateZ(6px)}
  100%{transform:rotateX(56deg) rotateZ(-45deg) translateZ(0)}}
@keyframes burst{0%{opacity:0;transform:translate(-50%,-50%) scale(.15)}
  14%{opacity:1}100%{opacity:0;transform:translate(-50%,-50%) scale(3)}}
@keyframes flash{0%{opacity:0}6%{opacity:.85}100%{opacity:0}}
@keyframes fly{0%{opacity:0;transform:translate(-50%,-50%) scale(.3)}
  14%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) translate(var(--dx),var(--dy)) scale(.85)}}
@keyframes notif{0%,100%{box-shadow:0 0 0 0 rgba(227,180,87,.55)}
  70%{box-shadow:0 0 0 11px rgba(227,180,87,0)}}
@keyframes textin{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
@keyframes beam{0%{opacity:0;transform:translateX(-50%) scaleY(.15)}55%{opacity:.9}
  100%{opacity:.55;transform:translateX(-50%) scaleY(1)}}
@keyframes motes{0%{opacity:0;transform:translateY(6px)}40%{opacity:.9}100%{opacity:0;transform:translateY(-26px)}}
@keyframes halo{0%,100%{opacity:.35}50%{opacity:.7}}
@keyframes sylpulse{0%,100%{transform:scale(1);opacity:.9}50%{transform:scale(1.55);opacity:.2}}
@keyframes livedot{0%,100%{opacity:1}50%{opacity:.25}}
.rise{animation:rise .4s ease both}
.land{animation:land .35s ease both}
.livedot{animation:livedot 1.2s ease-in-out infinite}

/* The ambient loops stop, and the world stops sliding between levels. */
@media(prefers-reduced-motion:reduce){
  *,*::after,*::before{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important}
  .plate{transition:none}
}

/* ============================================================
   Narrow. The world needs width, so below 1100px the rails collapse to
   sheets and the stage keeps the screen.
   ============================================================ */
/* No breakpoint here on purpose. An earlier version slid both panels off
   the sides below 1100px and gave nothing to slide them back with, so on a
   laptop window the tree and the rail were simply gone: the world lost its
   navigation and its inspector and looked like a bug. The handoff draws this
   at 1440 and says not to make it responsive, so below the width it needs
   the console scrolls sideways like any other fixed layout. Everything stays
   reachable, which is the only property that matters here. */

/* The group tier indents once more under its domain. */
.treerow.procrow.deep{padding-left:40px}

/* ============================================================
   Invitations. The handoff's screen 5, three columns.
   ============================================================ */
.inv{display:flex;flex-direction:column;height:calc(100vh - 168px);min-height:520px}

.invhead{
  display:flex;align-items:center;gap:11px;flex:none;
  padding:0 0 13px;border-bottom:1px solid var(--hairline);
}
.covbar{position:relative;width:170px;height:8px;border-radius:99px;background:rgba(242,241,250,.12)}
.covbar .now{position:absolute;left:0;top:0;bottom:0;border-radius:99px;
  background:var(--done);box-shadow:0 0 10px -1px var(--done)}
/* The projection is hatched, not a second solid bar: what the send would buy
   you has not happened yet, and a solid bar would say it had. */
.covbar .proj{position:absolute;top:0;bottom:0;border-radius:0 99px 99px 0;
  background:repeating-linear-gradient(45deg,rgba(139,152,240,.85) 0 4px,rgba(139,152,240,.3) 4px 8px)}
.invnote{font-size:11.5px;color:var(--ink66);line-height:1.5}

.invbody{flex:1;min-height:0;display:flex;margin:0 -18px -22px}
.invroster{
  width:376px;flex:none;display:flex;flex-direction:column;min-height:0;
  border-right:1px solid var(--hairline);background:var(--panel-soft);
}
.invrhead{padding:16px 18px 13px;border-bottom:1px solid var(--hairline)}
.invrhead .t{font-size:16px;font-weight:600}
.invrhead p{margin:5px 0 0;font-size:12.5px;color:var(--ink78);line-height:1.5}
.invpicks{display:flex;gap:8px;margin-top:13px}
.invpicks .btn5{height:29px;padding:0 11px;font-size:12px}
.btn5.gold{background:rgba(227,180,87,.12);border-color:rgba(227,180,87,.5);color:var(--gold)}
.btn5.gold:hover{background:rgba(227,180,87,.22)}

.invlist{flex:1;min-height:0;overflow:auto;padding:8px 10px 18px}
.invgroup{margin-bottom:6px}
.invgrow,.invrow{
  display:flex;align-items:center;gap:10px;width:100%;
  border:0;background:transparent;border-radius:8px;text-align:left;color:var(--ink);
}
.invgrow{padding:9px}
.invgrow:hover,.invrow:hover{background:rgba(255,255,255,.05)}
.invgrow .nm{flex:1;font-size:13px;font-weight:600}
.invgrow .meta{font-size:11.5px;color:var(--ink62);font-variant-numeric:tabular-nums}
.invgrow .meta.on{color:var(--link)}

.invrow{padding:8px 9px 8px 26px}
.invrow.on{background:rgba(67,56,202,.24)}
.invrow .who{flex:1;min-width:0}
.invrow .who .nm{display:block;font-size:13px;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.invrow .who .rl{display:block;font-size:11.5px;color:var(--ink62);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.invrow .chip{flex:none;font-size:11px;font-weight:700;padding:2px 7px;border-radius:5px}
.invrow .st{flex:none;width:86px;text-align:right;font-size:11px;color:var(--ink62)}
.invrow .st.gold{color:var(--gold)}
.invempty{padding:16px 9px;font-size:12.5px;color:var(--ink66);line-height:1.5}

/* A tick is a real control, so it reads as one whether or not it is on. */
.tk{
  width:17px;height:17px;flex:none;border-radius:5px;display:grid;place-items:center;
  font-size:10px;font-weight:700;
  background:rgba(255,255,255,.04);border:1px solid rgba(242,241,250,.3);color:transparent;
}
.tk.on{background:var(--action);border-color:#6D63FF;color:#fff}

.invmain{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}
.invtabs{
  display:flex;align-items:center;gap:10px;padding:14px 24px;
  border-bottom:1px solid var(--hairline);
}
.invseg{display:flex;gap:3px;margin-left:auto;padding:3px;border-radius:9px;
  background:rgba(255,255,255,.05);border:1px solid rgba(242,241,250,.14)}
.invseg button{
  display:flex;align-items:center;gap:7px;padding:6px 12px;border:0;border-radius:7px;
  background:transparent;color:var(--ink66);font-size:12.5px;font-weight:600;
}
.invseg button b{font-size:10.5px;font-weight:700;padding:1px 6px;border-radius:99px;
  background:rgba(242,241,250,.14);font-variant-numeric:tabular-nums}

.invscroll{flex:1;min-height:0;overflow:auto;padding:20px 24px 24px}
.invfrom{
  display:flex;align-items:center;gap:12px;max-width:720px;
  padding:12px 15px;border-radius:11px;
  background:rgba(255,255,255,.04);border:1px solid rgba(242,241,250,.14);
}
.invfrom .lb{font-size:12px;color:var(--ink66);width:44px;flex:none}
.invfrom .av{width:26px;height:26px;flex:none;border-radius:50%;background:var(--avatar);
  display:grid;place-items:center;font-size:11px;font-weight:700}
.invfrom .who{flex:1;min-width:0}
.invfrom .who .nm{display:block;font-size:13.5px;font-weight:600}
.invfrom .who .rl{display:block;font-size:11.5px;color:var(--ink66);margin-top:2px}

.invcols{display:flex;gap:20px;margin-top:20px;align-items:flex-start;flex-wrap:wrap}
.invedit{flex:1;min-width:340px}
.invsubj{display:flex;align-items:center;gap:11px;padding:11px 14px;border-radius:10px;
  background:rgba(255,255,255,.05);border:1px solid rgba(242,241,250,.18)}
.invsubj .lb{font-size:12px;color:var(--ink66);flex:none}
.invsubj input{flex:1;font:inherit;font-size:13.5px;font-weight:600;color:#fff;
  background:transparent;border:0;outline:none}
.invedit textarea{
  width:100%;box-sizing:border-box;margin-top:9px;
  font:inherit;font-size:13.5px;line-height:1.6;color:#fff;
  background:rgba(255,255,255,.05);border:1px solid rgba(242,241,250,.18);
  border-radius:11px;padding:13px 15px;outline:none;resize:none;
}
.invedit textarea:focus{border-color:var(--invited)}

/* Locked, and green rather than grey: this is a promise being kept, not a
   field that happens to be disabled. */
.invlock{
  display:flex;gap:11px;align-items:flex-start;margin-top:11px;padding:11px 14px;
  border-radius:10px;background:rgba(79,209,165,.07);border:1px solid rgba(79,209,165,.3);
}
.invlock .lk{flex:none;font-size:11px;font-weight:700;letter-spacing:.8px;
  text-transform:uppercase;color:var(--done);margin-top:1px}
.invlock .l1{font-size:13px;color:#fff;line-height:1.5}
.invlock .l2{font-size:11.5px;color:var(--ink78);margin-top:4px;line-height:1.45}

.invprev{width:320px;flex:none}
.pv{border-radius:13px;overflow:hidden;border:1px solid rgba(242,241,250,.18);
  background:rgba(9,8,26,.8)}
.pv.wa{background:#E5DDD5}
.pvchrome{display:flex;align-items:center;gap:9px;padding:9px 12px;
  background:rgba(255,255,255,.06);border-bottom:1px solid rgba(242,241,250,.12)}
.pv.wa .pvchrome{background:#075E54;border-bottom:0}
.pvchrome .dot{width:8px;height:8px;border-radius:50%;flex:none}
.pvchrome .nm{font-size:11.5px;font-weight:600;color:rgba(242,241,250,.86)}
/* .62, not the .6 the reference's inline styles use: that is under the floor,
   and a timestamp is still text somebody has to read. */
.pvchrome .at{margin-left:auto;font-size:11px;color:var(--ink62)}
.pvbody{padding:14px 15px;color:var(--ink)}
/* The real chrome of the channel, because a message read in a green bubble on
   a phone is not the same message as one read in a dark client. */
.pv.wa .pvbody{margin:12px;border-radius:10px 10px 10px 2px;background:#DCF8C6;
  box-shadow:0 1px 2px rgba(0,0,0,.2);color:#0B141A}
.pvsubj{font-size:14px;font-weight:700;margin-bottom:9px}
.pvtext{font-size:13px;line-height:1.6;white-space:pre-wrap}
.pvopt{font-size:12.5px;line-height:1.55;margin-top:10px;opacity:.82}

.invfoot{
  flex:none;height:72px;display:flex;align-items:center;gap:14px;padding:0 24px;
  border-top:1px solid var(--hairline);background:var(--chrome);
}
.invfoot .f1{flex:1;min-width:0}
.invfoot .f1 .t{font-size:13.5px;font-weight:600}
.invfoot .f1 .s{font-size:12px;color:var(--ink78);margin-top:3px}

.invside{
  width:314px;flex:none;overflow:auto;
  border-left:1px solid var(--hairline);background:var(--panel);
}
.invsec{padding:17px 18px;border-bottom:1px solid var(--hairline)}
.invmix{display:flex;flex-direction:column;gap:2px;margin-top:13px}
.invmix .r{display:flex;align-items:center;gap:9px;padding:6px 0}
.invmix .d{width:9px;height:9px;border-radius:2px;flex:none}
.invmix .n{flex:1;font-size:13px;color:var(--ink78)}
.invmix .v{font-size:12px;font-weight:700;color:var(--ink78)}

.invrules{display:flex;flex-direction:column;gap:11px;margin-top:11px}
.invrules .r{display:flex;gap:10px;align-items:flex-start}
.invrules .m{width:20px;height:20px;flex:none;border-radius:6px;display:grid;place-items:center;
  font-size:11px;font-weight:700;margin-top:1px;
  background:rgba(242,241,250,.08);color:var(--ink66)}
.invrules .m.good{background:rgba(79,209,165,.16);color:var(--done)}
.invrules .m.gold{background:rgba(227,180,87,.16);color:var(--gold)}
.invrules .t{font-size:13px;font-weight:600;line-height:1.35}
.invrules .s{font-size:12px;color:var(--ink78);margin-top:3px;line-height:1.45}

@media(max-width:1180px){
  .invbody{flex-direction:column;overflow:auto}
  .invroster,.invside{width:auto;border:0;border-bottom:1px solid var(--hairline)}
  .invlist{max-height:300px}
}

/* A screen the handoff designs at 1440 wide gets the room it was drawn for. */
.sheet.full{width:min(1420px,100%);height:100%}
.sheet.full .sheetbody{padding:16px 18px 22px}
.invstuck{padding:14px;margin:6px 0 12px;border-radius:11px;
  background:rgba(255,138,115,.08);border:1px solid rgba(255,138,115,.32)}
.invstuck .t{font-size:13px;font-weight:600;color:var(--broken)}
.invstuck p{margin:5px 0 11px;font-size:12px;color:var(--ink78);line-height:1.5}

/* ============================================================
   New customer. The handoff's screen 3, five steps.
   ============================================================ */
.nw{display:flex;height:calc(100vh - 168px);min-height:520px;margin:0 -18px -22px}

.nwsteps{
  width:250px;flex:none;padding:16px 12px;overflow:auto;
  border-right:1px solid var(--hairline);background:var(--panel-soft);
}
.nwstep{
  display:flex;align-items:flex-start;gap:11px;width:100%;
  padding:11px;border:0;background:transparent;border-radius:10px;text-align:left;
  color:var(--ink78);margin-bottom:3px;
}
.nwstep:hover{background:rgba(255,255,255,.05)}
.nwstep.on{background:var(--action-tint-hi);color:var(--ink)}
.nwstep .num{
  width:22px;height:22px;flex:none;border-radius:50%;display:grid;place-items:center;
  font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;
  background:rgba(242,241,250,.08);color:var(--ink62);
}
.nwstep.on .num{background:var(--action);color:#fff}
/* A visited step is green, so the rail says how far in you are without a bar. */
.nwstep.done .num{background:rgba(79,209,165,.18);color:var(--done)}
.nwstep .t{display:block;font-size:13px;font-weight:600}
.nwstep .s{display:block;font-size:11.5px;color:var(--ink62);margin-top:2px}

.nwmain{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0}
.nwbody{flex:1;min-height:0;overflow:auto;padding:22px 26px 26px;max-width:860px}
.nwh{font-size:21px;font-weight:600;letter-spacing:-.4px;margin:0}
.nwp{margin:7px 0 0;font-size:13px;color:var(--ink78);line-height:1.5;max-width:620px}
.nwnote{font-size:12px;color:var(--ink66);line-height:1.5}

.nwfoot{
  flex:none;height:64px;display:flex;align-items:center;gap:14px;padding:0 26px;
  border-top:1px solid var(--hairline);background:var(--chrome);
}
.nwfoot .nwnote{flex:1;text-align:center}

.nwurl{
  display:flex;align-items:center;gap:9px;margin-top:18px;max-width:560px;
  padding:0 0 0 13px;border-radius:10px;
  background:rgba(255,255,255,.05);border:1px solid var(--border2);
}
.nwurl .pre{font:12.5px var(--mono);color:var(--ink62)}
.nwurl input{flex:1;height:44px;border:0;background:transparent;color:var(--ink);
  font:13.5px var(--mono);outline:none}
.nwurl .btn5{margin:6px}
/* An indeterminate sweep, because the read has no progress to report. */
.nwsweep{margin-top:11px;height:3px;max-width:560px;border-radius:99px;
  background:rgba(242,241,250,.08);overflow:hidden}
.nwsweep i{display:block;width:34%;height:100%;border-radius:99px;
  background:var(--invited);animation:sweep 1s ease-in-out infinite}

.nwsrc{display:flex;flex-direction:column;gap:1px;margin-top:9px;max-width:720px}
.nwsrow{display:flex;align-items:center;gap:11px;padding:10px 11px;border-radius:9px}
.nwsrow:nth-child(odd){background:rgba(255,255,255,.03)}
.nwsrow .n{width:170px;flex:none;font-size:12.5px;font-weight:600}
.nwsrow .g{flex:1;min-width:0;font-size:12.5px;color:var(--ink78)}
.nwsrow .tg{flex:none;font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:5px;
  background:rgba(242,241,250,.08);color:var(--ink62)}
.nwsrow .tg.good{background:rgba(79,209,165,.16);color:var(--done)}
.nwsrow .tg.claim{background:rgba(227,180,87,.16);color:var(--gold)}
.nwsrow .tg.off{background:rgba(242,241,250,.06);color:var(--ink62)}

.nwfields{display:flex;flex-direction:column;gap:7px;margin-top:18px;max-width:720px}
.nwfield{display:flex;align-items:center;gap:13px;height:54px;padding:0 13px;
  border-radius:10px;background:rgba(255,255,255,.04);border:1px solid var(--hairline)}
.nwfield .lb{width:130px;flex:none;font-size:12.5px;color:var(--ink66)}
.nwfield input{flex:1;min-width:0;border:0;background:transparent;color:var(--ink);
  font:13.5px var(--sans);outline:none}
.nwfield .src{flex:none;font-size:11px;color:var(--ink62)}
/* A required field with nothing in it says so before the last step does. */
.nwfield.missing{background:rgba(255,138,115,.08);border-color:rgba(255,138,115,.4)}

/* Claims sit below a rule, never in the same list as the facts. */
.nwclaims{margin-top:22px;padding:15px;border-radius:12px;max-width:720px;
  background:rgba(227,180,87,.05);border:1px solid rgba(227,180,87,.35)}
.kicker.gold{color:var(--gold)}
.nwclaim{margin-top:11px;padding-top:11px;border-top:1px solid var(--hairline)}
.nwclaim .q{font-size:13.5px;font-weight:600;line-height:1.4}
.nwclaim .w{font-size:12px;color:var(--ink78);margin-top:4px;line-height:1.45}

.nwpacks{display:flex;flex-direction:column;gap:9px;margin-top:18px;max-width:720px}
.nwpack{display:flex;gap:12px;align-items:flex-start;width:100%;text-align:left;
  padding:14px;border-radius:12px;color:var(--ink);
  background:rgba(255,255,255,.04);border:1px solid var(--hairline)}
.nwpack:hover{background:rgba(255,255,255,.07)}
.nwpack.on{background:var(--action-tint);border-color:var(--invited)}
.nwpack .rd{width:16px;height:16px;flex:none;border-radius:50%;margin-top:2px;
  border:1px solid rgba(242,241,250,.35)}
.nwpack.on .rd{border:5px solid var(--action);background:#fff}
.nwpack .t{display:block;font-size:13.5px;font-weight:600}
.nwpack .sug{font-style:normal;font-size:10.5px;font-weight:700;padding:2px 7px;
  border-radius:99px;margin-left:7px;background:rgba(227,180,87,.18);color:var(--gold)}
.nwpack .w{display:block;font-size:12.5px;color:var(--ink78);margin-top:4px;line-height:1.45}
/* The pack's effect as numbers. A pack named but not counted is a decision
   nobody can weigh. */
.nwpack .fx{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-top:9px;
  font-size:12px;color:var(--ink66)}
.nwpack .fx i{font-style:normal;font-weight:700;font-variant-numeric:tabular-nums;
  padding:2px 7px;border-radius:5px}
.nwpack .fx i.bad{background:rgba(255,138,115,.16);color:var(--broken)}
.nwpack .fx i.mute{background:rgba(242,241,250,.08);color:var(--ink66)}

.nwdoms{display:flex;flex-direction:column;gap:9px;margin-top:18px;max-width:720px}
.nwdom{display:flex;gap:13px;align-items:flex-start;padding:14px;border-radius:12px;
  background:rgba(255,255,255,.04);border:1px solid var(--hairline)}
/* Switched off turns the card red and states the cost in words. */
.nwdom.off{background:rgba(255,138,115,.07);border-color:rgba(255,138,115,.35)}
.nwdom .sw, .nwbill .sw{width:38px;height:22px;flex:none;border-radius:99px;margin-top:1px;
  border:1px solid rgba(242,241,250,.22);background:rgba(242,241,250,.08);position:relative}
.nwdom .sw i, .nwbill .sw i{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:var(--ink62);transition:left .18s ease,background .18s ease}
.nwdom .sw.on, .nwbill .sw.on{background:rgba(79,209,165,.28);border-color:rgba(79,209,165,.5)}
.nwdom .sw.on i, .nwbill .sw.on i{left:18px;background:var(--done)}
.nwbill input{flex:1;min-width:0;border:0;background:transparent;color:var(--ink);
  font:13.5px var(--sans);outline:none}
.nwdom .t{font-size:13.5px;font-weight:600}
.nwdom .c{font-size:11.5px;color:var(--ink62);font-weight:400;margin-left:7px}
.nwdom .h{font-size:12.5px;color:var(--ink78);margin-top:3px}
.nwdom .cost{font-size:12.5px;color:var(--broken);margin-top:7px;line-height:1.45}

.nwreview{display:flex;flex-direction:column;gap:1px;margin-top:18px;max-width:720px}
.nwreview .r{display:flex;align-items:center;gap:13px;padding:11px 12px;border-radius:9px}
.nwreview .r:nth-child(odd){background:rgba(255,255,255,.03)}
.nwreview .k{width:130px;flex:none;font-size:12.5px;color:var(--ink66)}
.nwreview .v{flex:1;min-width:0;font-size:13px}
.nwreview .chg{flex:none;border:0;background:transparent;color:var(--link);font-size:12px}
.nwreview .chg:hover{color:var(--ink)}

.nwblock{margin-top:18px;padding:14px;border-radius:12px;max-width:720px;
  font-size:13px;line-height:1.5;color:var(--ink78);
  background:rgba(255,138,115,.08);border:1px solid rgba(255,138,115,.4)}
.nwblock b{color:var(--ink)}

.nwside{width:340px;flex:none;overflow:auto;
  border-left:1px solid var(--hairline);background:var(--panel)}
.nwsec{padding:17px 18px;border-bottom:1px solid var(--hairline)}
.nwkv{display:flex;align-items:baseline;gap:9px;margin-top:9px;font-size:12.5px}
.nwkv span{width:104px;flex:none;color:var(--ink66)}
.nwkv b{flex:1;min-width:0;font-weight:600;word-break:break-word}
.nwlist{display:flex;flex-direction:column;gap:2px;margin-top:11px}
.nwlist .r{display:flex;align-items:center;gap:9px;padding:6px 0;font-size:13px}
.nwlist .d{width:8px;height:8px;border-radius:2px;flex:none;background:var(--done)}
.nwlist .r.off .d{background:var(--broken)}
.nwlist .r.off .n{color:var(--ink62);text-decoration:line-through}
.nwlist .n{flex:1;color:var(--ink78)}
.nwlist .v{font-size:12px;font-weight:700;color:var(--ink78)}

@media(max-width:1180px){
  .nw{flex-direction:column;overflow:auto}
  .nwsteps,.nwside{width:auto;border:0;border-bottom:1px solid var(--hairline)}
  .nwsteps{display:flex;gap:4px;overflow-x:auto}
  .nwstep{width:auto;flex:none}
}

/* The rail names what it is. Without this the tree starts on a bare company
   row and the panel reads as a list of things rather than as the world. */
.treesec.first{padding-top:1px}
.treerow .caret{font-size:9px;color:var(--ink62);flex:none}

/* ============================================================
   The inspector, as the handoff draws it: a header with a pill, two
   stats, a stack of actions each with its own button, then sections of
   flat facts. The badge vocabulary is shared between the two so a count
   reads the same whether it is something to do or something known.
   ============================================================ */
.kickrow{display:flex;align-items:center;gap:9px}
.pill{
  font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:99px;
  background:rgba(242,241,250,.08);color:var(--ink78);letter-spacing:0;
  text-transform:none;
}
.kicker.link{color:var(--link)}
.railnote{margin:5px 0 0;font-size:11.5px;color:var(--ink62);line-height:1.45}

.acts{display:flex;flex-direction:column;gap:9px;margin-top:9px}
/* An action is tinted and carries a filled button. Never a fact. */
.act{
  display:flex;gap:11px;align-items:flex-start;padding:13px;border-radius:12px;
  background:linear-gradient(160deg,var(--action-tint-hi),var(--action-tint));
  border:1px solid rgba(139,152,240,.3);
}
.act.bad{background:rgba(255,138,115,.09);border-color:rgba(255,138,115,.38)}
.act.gold{background:rgba(227,180,87,.09);border-color:rgba(227,180,87,.38)}
.act .b{
  width:24px;height:24px;flex:none;border-radius:7px;display:grid;place-items:center;
  font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;margin-top:1px;
  background:rgba(242,241,250,.1);color:var(--ink);
}
.act.bad .b{background:rgba(255,138,115,.2);color:var(--broken)}
.act.gold .b{background:rgba(227,180,87,.2);color:var(--gold)}
.act .t{flex:1;min-width:0}
.act .h{font-size:13px;font-weight:600;line-height:1.35}
.act .s{font-size:12px;color:var(--ink78);margin-top:4px;line-height:1.45}
.act .btn5{flex:none;align-self:center}
.act.bad .btn5{background:var(--broken);border-color:transparent;color:#2A0D06;font-weight:700}
.act.bad .btn5:hover{background:#ff9d89}

/* A fact is flat, with no background until hover. Never an action. */
.facts2{display:flex;flex-direction:column;gap:1px;margin-top:7px}
.fact2{
  display:flex;gap:11px;align-items:flex-start;width:100%;padding:9px 7px;
  border:0;background:transparent;border-radius:9px;text-align:left;color:var(--ink78);
}
.fact2:hover{background:rgba(242,241,250,.05)}
.fact2[disabled]{cursor:default}
.fact2[disabled]:hover{background:transparent}
.fact2 .b{
  width:22px;height:22px;flex:none;border-radius:6px;display:grid;place-items:center;
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;margin-top:1px;
  background:rgba(242,241,250,.08);color:var(--ink62);
}
.fact2.done .b{background:rgba(79,209,165,.16);color:var(--done)}
.fact2.gold .b{background:rgba(227,180,87,.16);color:var(--gold)}
.fact2.bad .b{background:rgba(255,138,115,.16);color:var(--broken)}
.fact2 .t{flex:1;min-width:0}
.fact2 .h{display:block;font-size:13px;font-weight:600;color:var(--ink)}
.fact2 .s{display:block;font-size:11.5px;color:var(--ink62);margin-top:2px;line-height:1.4}
.fact2 .chev{color:var(--ink62);align-self:center}

/* The account list's badges: a word ("live", "band B") reads differently
   from a count, so they are not styled the same. */
.badge2{
  font-size:10.5px;font-weight:700;padding:2px 7px;border-radius:99px;
  background:rgba(242,241,250,.08);color:var(--ink78);
}
.badge2.num{background:transparent;color:var(--ink62);padding-right:2px;
  font-variant-numeric:tabular-nums}
.treerow .cnt.none{color:var(--broken)}

/* The company legend names its own rule, because "one square, one person"
   is the thing the whole floor rests on. */
.legtitle{
  font-size:10.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--ink62);margin-bottom:7px;
}
.legend .row.grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px 16px}
.legend .sw.off{background:rgba(242,241,250,.05);border:1px solid rgba(242,241,250,.28)}

/* The person Spren is talking to, standing in their own room at company level. */
.fig.live2{transform-origin:50% 100%;transform:rotateZ(45deg) rotateX(-58deg)}
.fig.live2 .head{width:19px;height:19px;margin-left:-9.5px}
.fig.live2 .body{width:29px;height:44px;margin-left:-14.5px;top:22px;border-radius:13px 13px 6px 6px}
.fig.live2 .halo{width:31px;height:9px;margin-left:-15.5px;bottom:-6px}
.livering{
  position:absolute;width:38px;height:38px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(227,180,87,.32),transparent 68%);
  animation:halo 2.6s ease-in-out infinite;
}
.citychip b.num{font-size:11px;font-weight:700;color:var(--ink78);margin-left:auto;padding-left:6px}

/* A figure's own name, above their head. Unlabelled, a crowd of identical
   green people says only "some people". */
.figname{
  transform:translate(-50%,calc(-100% - 58px));
  font-size:11px;font-weight:600;color:var(--ink78);white-space:nowrap;
  padding:2px 7px;border-radius:6px;
  background:rgba(9,8,26,.92);border:1px solid var(--hairline);
}
/* A step on the floor: what happens, and which number it is. */
.steplbl{
  display:flex;align-items:center;gap:11px;
  transform:translate(-50%,-50%);white-space:nowrap;
  padding:8px 11px;border-radius:9px;font-size:13.5px;font-weight:600;
  background:rgba(9,8,26,.94);border:1px solid var(--border2);
  box-shadow:0 12px 26px -12px rgba(0,0,0,.95);
}
.steplbl.bad{color:var(--broken);border-color:rgba(255,138,115,.4)}
.steplbl .sc,.plaque .sc{
  font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;
  padding:2px 7px;border-radius:99px;background:rgba(242,241,250,.1);color:var(--ink78);
}
.plaque .ph{display:flex;align-items:baseline;gap:11px}
.plaque .ph .nm{flex:1;min-width:0}
.plaque .sc.gold{background:rgba(227,180,87,.2);color:var(--gold)}
.plaque .sc.bad{background:rgba(255,138,115,.2);color:var(--broken)}
.plaque .sc.none{background:rgba(242,241,250,.08);color:var(--ink62)}

/* ============================================================
   The designed panels: rows, rank, matrix, kv.
   ============================================================ */
.panel5{max-width:900px}
.phead h2{margin:5px 0 0;font-size:21px;font-weight:600;letter-spacing:-.4px}
.phead p{margin:7px 0 0;font-size:13px;color:var(--ink78);line-height:1.5;max-width:640px}
.phead-note{margin:14px 0 0;font-size:13px;color:var(--ink78);line-height:1.5;
  padding:11px 13px;border-radius:10px;background:rgba(255,255,255,.04);
  border:1px solid var(--hairline)}

.prows{display:flex;flex-direction:column;gap:9px;margin-top:9px}
.prow{display:flex;gap:11px;align-items:flex-start;padding:13px;border-radius:12px;
  background:rgba(255,255,255,.04);border:1px solid var(--hairline)}
/* A row that needs a decision is tinted and carries a filled button, exactly
   as an action is in the rail. The vocabulary is shared on purpose. */
.prow.bad{background:rgba(255,138,115,.08);border-color:rgba(255,138,115,.36)}
.prow.gold{background:rgba(227,180,87,.08);border-color:rgba(227,180,87,.36)}
.prow.done{background:rgba(79,209,165,.07);border-color:rgba(79,209,165,.3)}
.prow .b{width:24px;height:24px;flex:none;border-radius:7px;display:grid;place-items:center;
  font-size:11.5px;font-weight:700;margin-top:1px;
  background:rgba(242,241,250,.1);color:var(--ink78)}
.prow.bad .b{background:rgba(255,138,115,.2);color:var(--broken)}
.prow.gold .b{background:rgba(227,180,87,.2);color:var(--gold)}
.prow.done .b{background:rgba(79,209,165,.2);color:var(--done)}
.prow .t{flex:1;min-width:0}
.prow .h{font-size:13.5px;font-weight:600;line-height:1.35}
.prow .s{font-size:12.5px;color:var(--ink78);margin-top:4px;line-height:1.45}
.prow .btn5{flex:none;align-self:center}
.prow.bad .btn5{background:var(--broken);border-color:transparent;color:#2A0D06;font-weight:700}

.prank{display:flex;flex-direction:column;gap:3px;margin-top:9px}
.prank .rr{display:flex;align-items:center;gap:11px;padding:6px 0}
.prank .n{width:210px;flex:none;font-size:13px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.prank .bar{position:relative;flex:1;height:8px;border-radius:99px;
  background:rgba(242,241,250,.1)}
.prank .bar i{position:absolute;left:0;top:0;bottom:0;border-radius:99px;
  background:var(--invited);box-shadow:0 0 10px -1px var(--invited)}
.prank .bar i.gold{background:var(--gold);box-shadow:0 0 10px -1px var(--gold)}
.prank .bar i.bad{background:var(--broken);box-shadow:0 0 10px -1px var(--broken)}
.prank .bar .tick{position:absolute;top:-4px;bottom:-4px;width:2px;
  background:var(--gold);box-shadow:0 0 6px var(--gold)}
.prank .v{width:26px;text-align:right;font-size:12.5px;font-weight:700}
.pill2{flex:none;width:64px;text-align:center;font-size:10.5px;font-weight:700;
  padding:3px 0;border-radius:99px;background:rgba(242,241,250,.08);color:var(--ink78)}
.pill2.gold{background:rgba(227,180,87,.2);color:var(--gold)}
.pill2.bad{background:rgba(255,138,115,.2);color:var(--broken)}

.pkv{display:flex;flex-direction:column;gap:1px;margin-top:9px}
.pkv .r{display:flex;gap:13px;padding:9px 0;border-bottom:1px solid var(--line2)}
.pkv .k{width:120px;flex:none;font-size:12.5px;color:var(--ink66)}
.pkv .v{flex:1;font-size:12.5px;color:var(--ink78);line-height:1.45}

/* Themes down, departments across. A grid says where a concern lives; a list
   of concerns only says that it exists. */
.pmatrix{display:grid;gap:6px 10px;margin-top:14px;align-items:center}
.pmatrix .ch{font-size:11px;color:var(--ink62);text-align:center;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pmatrix .rh{font-size:12.5px;color:var(--ink78);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.pmatrix .c{height:16px;border-radius:4px;background:rgba(242,241,250,.07)}
.pmatrix .c.ok{background:var(--done)}
.pmatrix .c.mixed{background:var(--gold)}
.pmatrix .c.bad{background:var(--broken)}
/* A designed panel brings its own header, so the sheet gives it only an Esc. */
.sheethead.bare{justify-content:flex-end;border-bottom:0;padding-bottom:0;background:transparent}
.pmatrix .rh{font-size:12.5px}

/* ============================================================
   The App store. One crate per process, and the crate is the
   argument: a box opens only when its process clears the line.
   The geometry is the handoff's own, so a crate here and a
   crate in the world are the same object at different sizes.
   ============================================================ */
.store5{display:flex;height:100%;min-height:0}
.stmain{flex:1;min-width:0;overflow:auto;padding:20px 24px 30px;
  background:radial-gradient(90% 60% at 30% 0%,rgba(139,152,240,.09),transparent 70%)}
.sttop{display:flex;align-items:center;gap:14px;margin-bottom:18px}
.sttop .s{font-size:12.5px;color:var(--ink62)}
.stsearch{width:250px;margin-left:auto;font:inherit;font-size:12.5px;padding:8px 12px;
  border-radius:9px;border:1px solid var(--hairline);background:rgba(255,255,255,.05);color:var(--ink)}
.stsearch:focus{outline:2px solid var(--act);outline-offset:1px}

/* ---- the crate ----
   The faces are built inline by store5.js because their geometry and shading
   are computed per crate. What stays here is the scene, the ground shadow,
   the beam and the motes: the parts that do not change with size. */
.cscene{position:absolute;width:0;height:0;transform-style:preserve-3d;
  transform:rotateX(56deg) rotateZ(-45deg)}
.cshadow{position:absolute;left:50%;border-radius:50%;background:rgba(0,0,0,.6)}
.cshadow.opened{background:rgba(227,180,87,.4)}
.cbeam{position:absolute;left:50%;transform:translateX(-50%);transform-origin:50% 100%;
  background:linear-gradient(rgba(255,240,201,0),rgba(255,240,201,.5));filter:blur(3px);
  animation:beam 1.1s ease-out both;pointer-events:none}
.cmote{position:absolute;width:3px;height:3px;border-radius:50%;background:var(--lit);
  box-shadow:0 0 6px 2px rgba(255,240,201,.8);animation:motes ease-out infinite}

/* ---- the two cards at the top ---- */
.sthero{display:flex;gap:16px;margin-bottom:22px}
.stfeature{position:relative;flex:1;min-width:0;display:flex;align-items:center;gap:20px;
  padding:20px 22px;border-radius:16px;overflow:hidden;
  border:1px solid rgba(227,180,87,.5);
  background:linear-gradient(150deg,rgba(227,180,87,.16),rgba(16,14,44,.4) 62%);
  box-shadow:0 26px 60px -30px rgba(227,180,87,.5);animation:rise .5s ease both}
.stfeature.held{border-color:rgba(255,138,115,.4);box-shadow:none;
  background:linear-gradient(150deg,rgba(255,138,115,.12),rgba(16,14,44,.4) 62%)}
.stfeature.locked{border-color:var(--hairline);box-shadow:none;background:rgba(255,255,255,.03)}
.stfeature .art{position:relative;width:186px;height:144px;flex:none}
.stfeature .txt{min-width:0;flex:1}
.stfeature .k{display:flex;align-items:center;gap:8px;font-size:10.5px;font-weight:700;
  letter-spacing:1.4px;text-transform:uppercase;color:var(--ink62)}
.stfeature .k .w{padding:2px 8px;border-radius:99px;background:rgba(227,180,87,.18);
  border:1px solid var(--gold);color:var(--lit);letter-spacing:.9px}
.stfeature .n{font-size:19px;font-weight:700;margin-top:8px;line-height:1.3;
  font-family:var(--mono);word-break:break-all}
.stfeature .s{font-size:12.5px;color:var(--ink78);margin-top:7px;line-height:1.5}
.stfeature .b{display:flex;gap:8px;margin-top:13px}
.stnext{width:262px;flex:none;border-radius:16px;padding:16px;
  border:1px solid var(--hairline);background:rgba(255,255,255,.035)}
.stnext .k{font-size:10.5px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--ink62);margin-bottom:11px}
.stnext .row{display:flex;align-items:center;gap:11px}
.stnext .row > div{min-width:0;flex:1}
.stnext .art{position:relative;width:64px;height:56px;flex:none}
.stnext .n{font-size:12px;font-weight:700;font-family:var(--mono);line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stnext .s{font-size:11.5px;color:var(--ink62);margin-top:3px}
.stnext .gauge{margin:12px 0 8px}
.stnext .s2{font-size:11.5px;color:var(--ink66);line-height:1.45;margin-bottom:11px}
.stnext > .btn5{width:100%;justify-content:center}

/* ---- filters and the shelf ---- */
.stfilters{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.stchip{display:flex;align-items:center;gap:8px;font:inherit;font-size:12.5px;font-weight:600;
  padding:8px 13px;border-radius:9px;border:1px solid var(--hairline);
  background:rgba(255,255,255,.04);color:var(--ink78)}
.stchip .d{width:9px;height:9px;border-radius:2px;flex:none;background:var(--act);
  box-shadow:0 0 8px -1px var(--act)}
.stchip.opened .d{background:var(--gold);box-shadow:0 0 8px -1px var(--gold)}
.stchip.held .d{background:var(--broken);box-shadow:0 0 8px -1px var(--broken)}
.stchip.locked .d{background:var(--none);box-shadow:none}
.stchip b{font-size:11px;font-weight:700;padding:2px 7px;border-radius:99px;
  background:rgba(242,241,250,.14)}
.stchip.on{color:#fff;border-color:var(--act);background:rgba(139,152,240,.18)}
.stchip.opened.on{border-color:var(--gold);background:rgba(227,180,87,.18)}
.stchip.held.on{border-color:var(--broken);background:rgba(255,138,115,.18)}
.stchip.locked.on{border-color:var(--none);background:rgba(242,241,250,.1)}
.stnote{font-size:11.5px;color:var(--ink62);margin-left:6px}

.stgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:16px}
.stcard{display:flex;flex-direction:column;border-radius:14px;overflow:hidden;cursor:pointer;
  background:rgba(255,255,255,.035);border:1px solid var(--hairline);
  transition:transform .18s,border-color .18s,box-shadow .18s;text-align:left}
.stcard.opened{border-color:rgba(227,180,87,.4)}
.stcard:hover{transform:translateY(-3px);border-color:var(--act)}
.stcard.on{border-color:var(--act);box-shadow:0 0 0 1px var(--act),0 18px 40px -20px rgba(0,0,0,.9)}
.stcard:focus-visible{outline:2px solid var(--act);outline-offset:2px}
.stcard .art{position:relative;height:130px;flex:none;overflow:hidden;
  border-bottom:1px solid var(--hairline);
  background:radial-gradient(70% 70% at 50% 62%,rgba(139,152,240,.08),rgba(9,8,26,.9) 72%)}
.stcard.opened .art{background:radial-gradient(70% 70% at 50% 62%,rgba(227,180,87,.24),rgba(9,8,26,.9) 72%)}
.stcard .tok{position:absolute;left:10px;top:10px;font-size:10px;font-weight:700;letter-spacing:.9px;
  text-transform:uppercase;padding:3px 7px;border-radius:5px;font-family:var(--mono);
  background:rgba(9,8,26,.82);border:1px solid var(--hairline);color:var(--ink66)}
.stcard.opened .tok{border-color:rgba(227,180,87,.5);color:var(--lit)}
.stcard .chip{position:absolute;right:10px;top:10px;font-size:10px;font-weight:700;letter-spacing:.9px;
  text-transform:uppercase;padding:3px 8px;border-radius:99px;
  background:rgba(242,241,250,.1);border:1px solid rgba(242,241,250,.28);color:var(--ink78)}
.stcard.opened .chip{background:rgba(227,180,87,.18);border-color:var(--gold);color:var(--lit)}
.stcard.held .chip{background:rgba(255,138,115,.18);border-color:var(--broken);color:#FFC0B2}
.stcard .body{padding:12px 13px 13px}
.stcard .n{font-size:12.5px;font-weight:700;line-height:1.35;word-break:break-all;color:var(--ink78)}
.stcard .n.mono{font-family:var(--mono);color:#fff}
.stcard .m{font-size:11.5px;color:var(--ink62);margin:4px 0 10px}
.stcard .foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:10px}
.stcard .sc,.stdetail .sc{font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink66)}
.stcard .sc{font-size:11.5px}
.stcard .sc.opened,.stdetail .sc.opened{color:var(--gold)}
.stcard .sc.held,.stdetail .sc.held{color:var(--broken)}
.stcard .foot .b{display:flex;gap:6px}
.stb{font:inherit;font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:7px;
  border:1px solid var(--hairline);background:rgba(255,255,255,.05);color:var(--ink78)}
.stb.gold{border-color:var(--gold);background:var(--gold);color:#231704}
.stempty{padding:40px;text-align:center;color:var(--ink62);border:1px dashed var(--hairline);
  border-radius:14px}

/* the gauge, tinted by the same three states */
.gauge.stg{display:block;height:6px}
.gauge.stg i{background:var(--none);box-shadow:none}
.gauge.stg i.opened{background:var(--gold);box-shadow:0 0 10px -1px var(--gold)}
.gauge.stg i.held{background:var(--broken);box-shadow:0 0 10px -1px var(--broken)}

/* ---- the detail panel ---- */
.stdetail{width:412px;flex:none;border-left:1px solid var(--hairline);
  background:rgba(10,9,32,.8);overflow:auto}
.stdetail .dhead{padding:16px 18px 15px;border-bottom:1px solid var(--hairline)}
.stdetail .dhead .k{display:flex;align-items:center;gap:8px}
.stdetail .dhead .chip{font-size:10.5px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;
  padding:3px 9px;border-radius:99px;background:rgba(242,241,250,.1);
  border:1px solid rgba(242,241,250,.28);color:var(--ink78)}
.stdetail .dhead .chip.opened{background:rgba(227,180,87,.18);border-color:var(--gold);color:var(--lit)}
.stdetail .dhead .chip.held{background:rgba(255,138,115,.18);border-color:var(--broken);color:#FFC0B2}
.stdetail .dhead .t{font-size:11.5px;color:var(--ink62)}
.stdetail .dhead .n{font-size:17px;font-weight:700;margin-top:9px;line-height:1.3;word-break:break-all}
.stdetail .dhead .n.mono{font-family:var(--mono)}
.stdetail .dhead .s{font-size:12.5px;color:var(--ink78);margin-top:7px;line-height:1.5}
.stdetail .dhead .g{display:flex;align-items:flex-end;gap:12px;margin-top:13px}
.stdetail .dhead .g > div{flex:1;min-width:0}
.stdetail .dhead .gn{font-size:11.5px;color:var(--ink62);margin-top:6px}
.stdetail .dhead .sc{font-size:19px}
.stdetail .dacts{display:flex;gap:8px;padding:14px 18px;border-bottom:1px solid var(--hairline)}
.stdetail .dfile{padding:14px 18px;border-bottom:1px solid var(--hairline)}
.stdetail .dfile .h{display:flex;align-items:center;gap:8px;margin-bottom:9px;
  font-size:10.5px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;color:var(--ink62)}
.stdetail .dfile .h .dot{width:7px;height:7px;border-radius:2px;background:var(--gold)}
.stdetail .dfile .h .stb{margin-left:auto;letter-spacing:0;text-transform:none}
.stdetail .dfile .body{font-family:var(--mono);font-size:11.5px;line-height:1.6;color:var(--ink78);
  white-space:pre-wrap;word-break:break-word;padding:11px 12px;border-radius:9px;
  background:rgba(0,0,0,.28);border:1px solid var(--hairline);max-height:230px;overflow:auto}
.stdetail .dsec{padding:14px 18px;border-bottom:1px solid var(--hairline)}
.strow{display:flex;gap:10px;align-items:flex-start;padding:8px 0}
.strow .m{width:22px;height:22px;flex:none;border-radius:6px;display:grid;place-items:center;
  font-size:11px;font-weight:700;margin-top:1px;background:rgba(242,241,250,.08);color:var(--ink66)}
.strow .m.done{background:rgba(79,209,165,.16);color:var(--done)}
.strow .m.bad{background:rgba(255,138,115,.16);color:var(--broken)}
.strow .m.gold{background:rgba(227,180,87,.16);color:var(--gold)}
.strow .n{font-size:12.5px;font-weight:600;line-height:1.35}
.strow .s{font-size:12px;color:var(--ink66);margin-top:3px;line-height:1.45}

@media(prefers-reduced-motion:reduce){
  .cscene,.cscene *,.cbeam,.cmote,.stfeature,.stspark,.stburst,.stflash{animation:none}
}

/* ---- the box that arrives shut ----
   The ceremony is presentation over data that is already true: the score
   decided whether the box is open, this decides only whether you have seen
   it happen. Replay puts it back, which is the tell that nothing persists. */
.stfeature .art[data-stopen]{cursor:pointer}
.stfeature .txt.sealed .k{display:flex;align-items:center;gap:8px;font-size:10.5px;
  font-weight:700;letter-spacing:2px;text-transform:uppercase;color:var(--ink62)}
.stfeature .txt.sealed .k .dot{width:7px;height:7px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 10px 2px rgba(227,180,87,.8)}
.stfeature .n2{font-size:21px;font-weight:700;margin-top:9px;line-height:1.25}
/* The text arrives after the burst, but only on the way in. Without the
   second class the phase flip re-renders the panel and restarts the delay,
   so the words blink out just as you go to read them. */
.stfeature .txt.shown.arriving{animation:textin .4s ease .6s both}
.btn5.big{font-size:14px;margin-top:17px;padding:12px 20px;border-radius:10px;
  animation:notif 2s ease-out infinite}
.btn5.ghost{background:transparent;color:var(--ink66);border:1px solid var(--hairline)}

.stspark{position:absolute;left:60%;top:76%;width:4px;height:4px;border-radius:50%;
  background:var(--lit);pointer-events:none;box-shadow:0 0 8px 2px rgba(255,240,201,.85);
  animation:fly cubic-bezier(.15,.7,.3,1) both}
.stspark.big{width:6px;height:6px;background:var(--gold)}
.stburst{position:absolute;left:60%;top:76%;width:130px;height:130px;border-radius:50%;
  border:2px solid rgba(255,240,201,.95);pointer-events:none;
  animation:burst .85s cubic-bezier(.2,.7,.3,1) .5s both}
.stburst.r2{width:96px;height:96px;border:0;
  background:radial-gradient(rgba(255,240,201,.55),rgba(227,180,87,0) 68%);
  animation:burst 1s cubic-bezier(.2,.7,.3,1) .52s both}
.stflash{position:absolute;inset:-40px;pointer-events:none;
  background:radial-gradient(circle at 60% 76%,rgba(255,247,222,.9),rgba(255,240,201,0) 62%);
  animation:flash 1s ease-out .5s both}

.stnotif{display:flex;align-items:center;gap:8px;font:inherit;font-size:12.5px;font-weight:700;
  padding:8px 13px;border-radius:999px;margin-left:auto;
  border:1px solid var(--hairline);background:rgba(255,255,255,.04);color:var(--ink62)}
.stnotif .d{width:7px;height:7px;border-radius:50%;background:rgba(242,241,250,.3)}
.stnotif.on{border-color:var(--gold);background:rgba(227,180,87,.16);color:var(--gold);
  animation:notif 2s ease-out infinite}
.stnotif.on .d{background:var(--gold);box-shadow:0 0 9px 2px rgba(227,180,87,.85)}
.sttop .stsearch{margin-left:0}

/* ---- the directory, deliberately not the shelf ----
   The shelf above is crates: files written from this company's own words,
   scored against the line, free. This is a list: other people's products,
   nothing to open, nothing scored, and a purchase at the end of it. The two
   must not be mistakable at a glance, so they share no shape and no colour. */
.stelse{margin-top:34px;padding-top:22px;border-top:1px solid var(--hairline)}
.stelse-note{font-size:12.5px;color:var(--ink66);line-height:1.55;max-width:70ch;margin:6px 0 16px}
.stelse-list{display:flex;flex-direction:column;gap:10px}
.stelse-row{padding:14px 16px;border-radius:12px;border:1px solid var(--hairline);
  background:rgba(255,255,255,.025)}
.stelse-row .h{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.stelse-row .n{font-size:13.5px;font-weight:700}
.stelse-row .tag{font-size:10.5px;font-weight:600;letter-spacing:.3px;padding:2px 8px;
  border-radius:99px;background:rgba(242,241,250,.08);color:var(--ink62);
  border:1px solid var(--hairline)}
.stelse-row .tag.paid{background:rgba(227,180,87,.14);border-color:rgba(227,180,87,.5);
  color:var(--gold)}
.stelse-row .s{font-size:12.5px;color:var(--ink78);margin-top:7px;line-height:1.5}
.stelse-row .why{font-size:12px;color:var(--ink66);margin-top:6px;line-height:1.5;
  padding-left:10px;border-left:2px solid var(--hairline)}
.stelse-row .for{font-size:11.5px;color:var(--ink62);margin-top:7px}
.stelse-row .checks{margin:9px 0 0;padding-left:18px;font-size:12px;color:var(--ink66);
  line-height:1.55}
.stelse-row .checks li{margin-bottom:3px}
.stelse-row .stb{display:inline-block;margin-top:11px;text-decoration:none}
