/* sleek.css, the weight layer. Loads last, on purpose.

   Anand, 2026-08-07, on the round-three build: "It needs to look modern, it
   needs to look sleek, not too heavy, clunky, vibe-coded, and thick. The
   vibe-coded is thick. But the sleekness is what I'm looking for."

   `checks/weight.mjs` turned that into six numbers and measured the build
   before this file existed:

     BORDERS 523 across ten screens    front desk alone drew 96
     SHADES  8 distinct border colours on Today
     SIZES   12 distinct font sizes on Today
     RADII   7 distinct corner radii on Teacher Training
     CHROME  137px of bars above the first pixel of content
     NEST    3 frames around one fact

   The cause was never one bad screen. It was four habits repeated
   everywhere, which is why this is a token and rule change applied at once
   rather than a screen rebuild:

     1. A border on every table CELL. Six columns times ten rows is sixty
        bordered elements to draw ten row separators. The border belongs on
        the row.
     2. Three signals for one meaning. A status chip drew a tinted
        background AND a tinted border AND coloured text. Any two of those
        say it; all three shout it. The border goes.
     3. A border AND a shadow on the same card. Either defines an edge. Both
        is the single most reliable tell of a generated interface.
     4. Type sizes accumulated one screen at a time until twelve of them
        were in play, four sitting within 3px of each other where no reader
        can tell them apart. They stopped carrying hierarchy and started
        being noise.

   Nothing here changes a colour, a layout or a word. It changes how heavily
   the same content is drawn, so it lands on all 71 screens at once and no
   screen has to be rebuilt to get it.

   Density is a token, not a rewrite: set data-density on <html> to
   "compact" or "roomy" to see the same screens tighter or looser. */

:root {
  /* ---- one hairline, two weights ----
     Was eight distinct border colours on a single screen, because every
     semantic chip brought its own tint. A line is structure, not meaning;
     meaning is carried by the fill and the text. */
  --w-line: rgba(36, 28, 43, 0.09);
  --w-line-strong: rgba(36, 28, 43, 0.15);

  /* The two old line tokens are re-pointed at the new ones rather than left
     alongside them. Adding a hairline without retiring what it replaces is
     how a palette gets to eight border colours in the first place, and it
     is what the first run of this file actually did: SHADES went from 8 to
     9 because --line and --line-2 were still in play underneath. */
  --line: var(--w-line);
  --line-2: var(--w-line-strong);

  /* ---- density ----
     The three values Anand picks between. Everything spatial derives from
     these, so changing one line changes the whole product's breathing. */
  --w-pad: 15px;
  --w-pad-y: 11px;
  --w-gap: 16px;
  --w-row-y: 11px;

  /* ---- type, seven steps on a 1.25 major third ----
     ui-fundamentals.md:23-24, "pick 4-6 steps and stop. Six sizes on a page
     is a design; eleven is an accident." Micro is the seventh and it earns
     its place: table column headers genuinely need to sit below body text. */
  --t-micro: 11px;
  --t-sm: 12px;
  --t: 13px;
  --t-md: 16px;
  --t-lg: 20px;
  --t-xl: 26px;
  --t-2xl: 32px;

  /* ---- three radii ----
     Was seven. Mixed radii is named as the second most common AI-build tell
     in ui-fundamentals.md:76-78. Small is anything you click, medium is a
     surface, large is a surface that floats. */
  --r-sm: 6px;
  --r: 10px;
  --r-lg: 14px;

  /* ---- one shadow that is used, one that floats ----
     A card carrying both a border and a shadow-sm was drawing its edge
     twice. Cards keep the border and lose the shadow. The shadow is
     reserved for things genuinely above the page: drawers, popovers,
     the command palette. */
  --shadow-sm: none;
  --shadow: 0 4px 16px rgba(36, 28, 43, 0.07);
  --shadow-lg: 0 16px 48px rgba(36, 28, 43, 0.13);

  /* ---- chrome ----
     137px of bars sat above the first pixel of content on every screen, all
     day, on a 950px viewport. That is one seventh of her window spent on
     furniture. */
  --topbar-h: 54px;
}

html[data-density="compact"] {
  --w-pad: 12px;
  --w-pad-y: 8px;
  --w-gap: 12px;
  --w-row-y: 8px;
  --topbar-h: 48px;
}
html[data-density="roomy"] {
  --w-pad: 20px;
  --w-pad-y: 15px;
  --w-gap: 22px;
  --w-row-y: 14px;
  --topbar-h: 60px;
}

/* ---------- tables: one line per row, not one per cell ----------
   This is the single biggest weight reduction in the file. A ten-row, six
   column table drew sixty bordered elements to communicate nine
   separations. `border-collapse: collapse` is already set on `.tbl`, so the
   row carries the line correctly and it renders identically. */
.tbl td,
.tbl th {
  border-bottom: 0;
}
.tbl thead tr {
  border-bottom: 1px solid var(--w-line-strong);
}
.tbl tbody tr + tr {
  border-top: 1px solid var(--w-line);
}
.tbl td {
  padding: var(--w-row-y) 14px;
}
.tbl th {
  padding: 8px 14px;
  font-size: var(--t-micro);
}
/* A hover that only changes the background reads as a highlight. Pair it
   with the row line going quiet so the hovered row lifts out of the stack
   rather than being painted over. */
.tbl tbody tr:hover + tr {
  border-top-color: transparent;
}

/* ---------- cards: one edge, not two ---------- */
.card {
  border-color: var(--w-line);
  box-shadow: none;
}
.card--pad {
  padding: var(--w-pad) calc(var(--w-pad) + 3px);
}
/* The head of a card is already distinguished by weight and size. A rule
   under it is a third signal for a boundary the eye has already found.
   Kept only where a table starts immediately underneath, because there the
   line is doing real work separating two different kinds of row. */
.card__head {
  padding: var(--w-pad-y) calc(var(--w-pad) + 3px);
  border-bottom: 0;
}
.card__head:has(+ .tblwrap),
.card__head:has(+ table),
.card__head:has(+ .tbl) {
  border-bottom: 1px solid var(--w-line);
}

/* A card inside a card is two frames around one fact. The inner one loses
   its frame and keeps its padding, so the grouping survives and the weight
   does not. NEST was 3 on seven of ten screens. */
.card .card,
.card .panel,
.panel .card {
  border: 0;
  box-shadow: none;
  background: transparent;
}

/* ---------- chips and badges: fill or line, never both ----------
   Every one of these drew a tinted background, a tinted border and coloured
   text. Three signals for one meaning, and the reason a single screen
   carried eight distinct border colours. */
.cchip {
  border-color: transparent;
  background: var(--plum-050);
  font-size: var(--t-sm);
  padding: 6px 11px;
}
.cchip:hover {
  background: #ece2f3;
}
.chip,
.pill,
.tag,
.badge,
.status,
.vc-badge {
  border-color: transparent;
}

/* `.chip` was `display: block`, so a chip carrying an icon stacked the icon
   above its own label and rendered 43px tall instead of about 26px. Every
   apparatus filter on the video library was double height. This predates
   the weight pass, it is identical on the deployed build, and it was found
   by looking at a screenshot rather than by any check. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chip svg {
  width: 14px;
  height: 14px;
  flex: none;
}

/* Banners say one thing loudly. They keep their fill and lose their outline,
   which is the same trade as the chips and for the same reason.

   A coloured left rule was tried here first and reverted. It looks right in
   isolation and it is a real pattern, but it put the accent colour back into
   the border palette one banner variant at a time, which is the exact habit
   this file exists to end. The fill and the text already carry the meaning. */
.banner {
  border: 0;
  border-radius: var(--r-sm);
  padding: var(--w-pad-y) var(--w-pad);
}

/* A button with no border rule of its own inherits the user agent's
   `2px outset ButtonBorder`, which computes to a black 2px border. Every
   tab on every screen was carrying one. Any class rule that sets a real
   border outranks this by specificity, so nothing intentional is lost. */
button {
  border: 0;
}

/* ---------- three stacked navigation levels ----------
   `01-dashboard-layout.md:255-257` is the teardown's own answer to what
   "vibe-coded" looks like, and it is not a colour or a font. It is Tabler:
   "a 60px header, then a second 48px nav bar, then an OVERVIEW eyebrow
   above a Dashboard title. Roughly 170 vertical pixels are consumed before
   any data. Three stacked bars of chrome." And at :610-612, on the default
   shadcn dashboard: "the three stacked navigation levels before any
   content ... are the additional tells."

   We ship the same three levels: the topbar, the section strip, and a tab
   row. All three were drawn as full width bars, so nothing told a person
   which one answers "where am I" and which answers "which slice of this".

   They are not made equal here, they are made unequal. The strip stays a
   bar because it IS navigation. The tab row stops being a bar at all and
   becomes a segmented control sized to its own content, which is what it
   has always actually been: a switch inside one screen. */
.tabs {
  display: inline-flex;
  max-width: 100%;
  border-bottom: 0;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 3px;
  gap: 2px;
  margin-bottom: var(--w-gap);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar {
  display: none;
}
.tab {
  padding: 6px 12px;
  margin-bottom: 0;
  border-bottom: 0;
  border-radius: calc(var(--r-sm) - 2px);
  font-size: var(--t);
  font-weight: 550;
  white-space: nowrap;
  /* --muted on the new --surface-2 track measures about 4.3:1, which is
     under the 4.5:1 floor in ui-fundamentals.md:36-37. It passed while the
     track was white. Moving the track means re-checking the text on it. */
  color: var(--ink-2);
}
.tab.active {
  background: var(--surface);
  color: var(--ink);
  border-bottom-color: transparent;
}

/* The rail already says which room you are standing in, in plum, at full
   contrast. The strip repeating that in a solid plum pill was the same
   fact stated twice at the same volume, and it made a second bar shout as
   loudly as the first. The strip now says which SECTION, quietly. */
.roomstrip .nav-item.active {
  background: var(--plum-050);
  color: var(--plum-700);
  font-weight: 600;
}
.roomstrip .nav-item.active svg {
  color: var(--plum);
}

/* ---------- the metric row becomes a metric band ----------
   `01-dashboard-layout.md:784-786`: "shadcn-admin, Umami, Tabler and Ant
   Design Pro all lead with a KPI row, and all four are the least
   distinctive screens in the set. That correlation is not a coincidence: a
   KPI row is the layout you reach for when you have not decided what the
   user's first action is."

   And the recommendation at :788-792: the studio app should open on today,
   "with the metric strip as a 62px band above it rather than as the page",
   because "a studio owner at 7am wants to know which class is short and who
   has not paid, not what their 30-day revenue trend is."

   The 62px band spec is at :799-801, taken from Plausible: one band,
   hairline separators, small labels, 20px values, deltas inline.

   Our `.metricrow` is not the generic KPI wall those four ship. It is a
   control: clicking a cell redraws the chart, and exactly one number on the
   screen is set in Playfair. That is a real Von Restorff move and it stays.
   What changes is the height. It was drawn as a wall of cards and is now
   the band the research asks for. */
.metricrow {
  border-color: var(--w-line);
}
.metric {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "label label"
    "value meta";
  align-items: baseline;
  column-gap: 8px;
  padding: 9px 16px 10px;
  border-left-color: var(--w-line);
}
.metric__label {
  grid-area: label;
  margin-bottom: 2px;
  font-size: var(--t-micro);
}
.metric__value {
  grid-area: value;
  font-size: var(--t-lg);
}
.metric__meta {
  grid-area: meta;
  margin-top: 0;
  font-size: var(--t-micro);
}
/* The one focal number survives, at band height rather than card height.
   Pinned to --t-xl rather than to a nearby round number: 27px would be a
   ninth type size on Today, and weight.mjs caught it immediately. A scale
   only holds if new values join it instead of sitting beside it. */
:root {
  --fs-focal: var(--t-xl);
}

/* `.kpi-grid` IS the generic wall, eleven of them on the studio surface
   alone, every one a hard `repeat(4, 1fr)` of bordered cards. Rule 1 of
   BUILD-CONTRACT.md bans exactly that shape and the ban was never enforced.
   Same treatment, one rule, every instance at once: a band with hairline
   separators instead of four boxes with four borders. */
.kpi-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  grid-template-columns: none;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--w-line);
  border-radius: var(--r);
  overflow: hidden;
}
.kpi {
  border: 0;
  border-left: 1px solid var(--w-line);
  border-radius: 0;
  box-shadow: none;
  padding: 10px 16px 11px;
  min-width: 0;
}
.kpi:first-child {
  border-left: 0;
}
.kpi__label {
  font-size: var(--t-micro);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi__value {
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* ---------- chrome: fewer bars, shorter bars ---------- */
.topbar {
  height: var(--topbar-h);
  border-bottom: 1px solid var(--w-line);
}
.roomstrips {
  top: var(--topbar-h);
}
/* Aligned to the page gutter, not to an arbitrary inset. A strip that
   starts 16px left of the heading under it reads as a floating bar rather
   than as part of the same column. */
.roomstrip {
  padding: 5px 28px;
}
.roomstrip .nav-item {
  padding: 5px 10px;
  font-size: var(--t-sm);
}
.sidebar {
  border-right: 1px solid var(--w-line);
}
.page-head {
  margin-bottom: var(--w-gap);
}

/* ---------- type: collapse the strays onto the scale ----------
   Twelve sizes became seven. Hierarchy moves onto weight, which reads at
   least as clearly and costs no vertical space (ui-fundamentals.md:29-30). */
.card__title {
  font-size: var(--t);
  font-weight: 650;
  letter-spacing: 0.01em;
}
.page-head h1,
.page-head h2 {
  font-size: var(--t-xl);
  line-height: 1.15;
  letter-spacing: -0.02em;
}
.page-head p,
.page-sub,
.sub {
  font-size: var(--t);
  color: var(--ink-2);
}
.muted,
.hint,
.note,
.caption {
  font-size: var(--t-sm);
}
.metric b,
.metric strong,
.kpi b,
.stat b {
  font-size: var(--t-xl);
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}

/* ---------- the eyebrow ----------
   Anand's standing rule, and he was blunt about it: uppercase tracked micro
   labels sitting above a headline are "disgusting" and never ship. The
   topbar caption was rendering ONE LOCATION beside the studio name.
   Column headers in a data table are exempt and stay uppercase: that is a
   table convention a reader parses as structure, not a label pretending to
   be a category. */
.view-caption,
.nav-section,
.eyebrow,
.overline,
.kicker {
  text-transform: none;
  letter-spacing: 0;
}

/* `.section-label` was 11px, weight 700, 0.08em tracking, uppercase, muted.
   That is the eyebrow, exactly, and there are 111 of them across the studio
   and HQ surfaces. The source text is already written in sentence case, so
   dropping the transform is enough to make it read as the section heading
   it always was. It also stops shouting at a size too small to be read
   comfortably, which is the trade an eyebrow always loses. */
.section-label {
  font-size: var(--t);
  font-weight: 650;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: var(--w-gap) 0 8px;
}

/* Panel form labels were the same shape as `.section-label`: 11px, weight
   700, 0.07em tracking, uppercase, muted. 235 of them across the panel
   files. A form label has one job, which is to name the field clearly
   enough that nobody has to read the placeholder, and 11px shouting is
   worse at that than 12px speaking. Placeholder-as-label is the failure
   this guards against, ui-fundamentals.md:85-86. */
.pn__f > label {
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-2);
  margin-bottom: 5px;
}
.view-caption {
  font-size: var(--t-sm);
  color: var(--muted);
}

/* A room holding one section does not need a strip to choose between. The
   room name in the rail has already said it, and a lone pill under the
   topbar reads as a stray tab. Hidden with display, not removed, because
   tour.js clicks `.nav-item[data-view]` for 83 authored steps and a
   programmatic click still lands on a display:none element. */
.roomstrip:has(.nav-item[data-view]:only-of-type) {
  display: none;
}

/* ---------- inputs and buttons: one radius, one line ---------- */
.btn,
.input,
input[type="text"],
input[type="search"],
input[type="email"],
input[type="number"],
select,
textarea,
.tab {
  border-radius: var(--r-sm);
}
.btn--ghost,
.btn--quiet {
  border-color: var(--w-line-strong);
}

/* Focus is the one place weight is correct. It has to be unmissable, and
   ui-fundamentals.md:90-92 names a missing focus-visible as both an
   accessibility failure and the reason keyboard users get lost. */
:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ---------- settings scope ----------
   research/H-live-reference.md:47-51, from Vercel: "name the scope
   explicitly in the settings header, don't make the user infer it." Nine
   settings categories shipped as peers, three about Maria and six about the
   studio, with nothing saying which was which. Changing a studio setting
   changes what everyone else sees, and that is not a thing to find out
   afterwards. Two headings in the rail, not a toggle: a toggle would hide
   six of the nine behind a control, and this round exists because of
   nesting. */
.setnav__scope {
  padding: 14px 4px 5px;
}
.setnav__scope:first-child {
  padding-top: 2px;
}
.setnav__scope b {
  display: block;
  font-size: var(--t);
  font-weight: 650;
  color: var(--ink);
}
.setnav__scope span {
  display: block;
  font-size: var(--t-sm);
  color: var(--muted);
  margin-top: 1px;
}

/* The avatar is a control now, so it has to look like one and take focus. */
.avatar--act {
  cursor: pointer;
}
.avatar--act:hover {
  box-shadow: 0 0 0 2px var(--plum-050);
}
.avatar--act:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
}

/* ---------- the shortcut sheet ----------
   research/H-live-reference.md LANE 2: Stripe binds `?` globally and says so
   in its own docs, and a pattern gallery in the same lane catalogues 32 real
   products shipping the same sheet. A convention people arrive already
   knowing. */
.keys {
  position: fixed;
  inset: 0;
  z-index: 10070;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(36, 28, 43, 0.4);
  animation: keys-in 0.16s ease-out both;
}
.keys__card {
  width: min(620px, calc(100vw - 40px));
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: 20px 22px 18px;
}
.keys__h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.keys__t {
  font-family: var(--font-brand);
  font-size: var(--t-lg);
  letter-spacing: -0.015em;
  color: var(--ink);
}
.keys__x {
  background: none;
  border: 0;
  font-size: 20px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--r-sm);
}
.keys__x:hover {
  background: var(--surface-2);
  color: var(--ink);
}
.keys__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 6px 28px;
}
.keys__gt {
  font-size: var(--t-sm);
  font-weight: 650;
  color: var(--ink);
  margin: 10px 0 4px;
}
.keys__r {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 4px 0;
}
.keys__r kbd {
  flex: none;
  min-width: 46px;
  text-align: center;
  font-family: var(--font-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 3px 7px;
}
.keys__r span {
  font-size: var(--t);
  color: var(--ink-2);
}
.keys__foot {
  margin-top: 16px;
  padding-top: 13px;
  border-top: 1px solid var(--w-line);
  font-size: var(--t);
  color: var(--ink-2);
}
.keys__link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--plum);
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
@keyframes keys-in {
  from {
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .keys {
    animation: none;
  }
}

/* ---------- the jump palette ---------- */
.jumpp {
  position: fixed;
  inset: 0;
  z-index: 10080;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  background: rgba(36, 28, 43, 0.38);
}
.jumpp__card {
  width: min(560px, calc(100vw - 40px));
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.jumpp__in {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--w-line);
  border-radius: 0;
  padding: 15px 18px;
  font: inherit;
  font-size: var(--t-md);
  color: var(--ink);
  background: none;
}
.jumpp__in:focus {
  outline: none;
}
.jumpp__list {
  max-height: 46vh;
  overflow-y: auto;
  padding: 6px;
}
.jumpp__o {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  padding: 8px 12px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}
.jumpp__o.on,
.jumpp__o:hover {
  background: var(--plum-050);
}
.jumpp__o span {
  font-size: var(--t);
  font-weight: 550;
}
.jumpp__o em {
  font-style: normal;
  font-size: var(--t-sm);
  color: var(--muted);
  flex: none;
}
.jumpp__none {
  padding: 14px 12px;
  font-size: var(--t);
  color: var(--muted);
}
.jumpp__foot {
  border-top: 1px solid var(--w-line);
  padding: 8px 14px;
  font-size: var(--t-sm);
  color: var(--muted);
}
.jumpp__foot kbd {
  font-family: var(--font-ui);
  font-size: var(--t-micro);
  font-weight: 600;
  background: var(--surface-2);
  border-radius: 4px;
  padding: 2px 5px;
  margin-right: 3px;
  color: var(--ink-2);
}

/* ---------- the Powerhouse ----------
   04-distinctiveness.md:443: "Jessica's logo is a swirl of concentric arcs.
   Make that geometry the product's capacity primitive", drawn "at one fixed
   geometry and one fixed sweep, filling clockwise". Three arcs, one per
   input, composite in the middle. A short ring reads before any number does. */
.ph {
  padding: var(--w-pad) calc(var(--w-pad) + 3px);
}
.ph__main {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}
.ph__mark {
  position: relative;
  flex: none;
  width: 120px;
  height: 120px;
}
.ph__mark svg {
  width: 120px;
  height: 120px;
  transform: rotate(-90deg);
}
.ph__bg {
  fill: none;
  stroke: var(--surface-2);
  stroke-width: 7;
}
.ph__arc {
  fill: none;
  stroke-width: 7;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .ph__arc {
    transition: none;
  }
}
.ph__score {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-brand);
  font-size: var(--t-xl);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.ph__say {
  flex: 1 1 320px;
  min-width: 0;
}
.ph__t {
  font-family: var(--font-brand);
  font-size: var(--t-lg);
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: 6px;
}
.ph__say p {
  font-size: var(--t);
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0 0 6px;
}
.ph__note {
  font-size: var(--t-sm) !important;
  color: var(--muted) !important;
}
.ph__rows {
  margin-top: var(--w-gap);
  border-top: 1px solid var(--w-line);
}
.ph__row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 2px;
  text-decoration: none;
  color: var(--ink);
}
.ph__row + .ph__row {
  border-top: 1px solid var(--w-line);
}
.ph__row:hover {
  background: var(--surface-2);
}
.ph__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}
.ph__l b {
  display: block;
  font-size: var(--t);
  font-weight: 600;
}
.ph__l em {
  display: block;
  font-style: normal;
  font-size: var(--t-sm);
  color: var(--muted);
}
.ph__v {
  font-size: var(--t-lg);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.ph__w {
  font-size: var(--t-sm);
  color: var(--muted);
  white-space: nowrap;
}
.ph__go {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--plum);
  white-space: nowrap;
}
@media (max-width: 900px) {
  .ph__row {
    grid-template-columns: 10px minmax(0, 1fr) auto;
  }
  .ph__w,
  .ph__go {
    display: none;
  }
}
