/* =============================================================================
   74-dev-tools.css — v15.866

   THE DEV TOOLS PAGE. Sole owner of its presentation: every rule here was moved
   out of 37-profile-settings.css and rewritten, rather than layered on top of
   it, so there is exactly one place this page's look is decided and no cascade
   to fight. 37 keeps the user-facing announcement MODAL (what a recipient sees)
   — that is not dev UI and was deliberately left alone.

   THE BRIEF: simplistic, minimal, black and white, soft.

   What that meant in practice, and why the old page failed it:

   1. NO ACCENT COLOUR. The page was carrying three purples (#7c5cf0 tabs,
      rgba(214,77,255) buttons and bars, #c4b5fd chips). An accent earns its
      place by marking ONE thing as special; when every control has it, it marks
      nothing and just adds noise. Selection and actions are carried by
      INVERSION instead — white fill, black text — the strongest signal a
      two-ink palette has, at no cost in hue.

      THE EXCEPTION, and it is a deliberate one: the Shelfd+ / gifted tags keep
      their colour. There hue is not decoration, it is the datum — lavender for
      a paying account, warm for one you comped — and telling those two apart at
      a glance is the only reason the tag is on the row.

   2. HIERARCHY BY WEIGHT AND OPACITY, NOT SIZE AND COLOUR. The explainer under
      each card was `400 15px` in PURE WHITE — the same colour as the heading and
      nearly the same size, so a paragraph explaining what a number means shouted
      as loudly as the number. Body copy is now 300 at 55% white. Nothing on the
      page competes with its own title.

   3. SOFT, NOT BOXY. Hairlines at 6-8% rather than 9-12%, wider radii, more air
      inside each card. The old 0.9px borders at 9% drew a hard rectangle around
      every one of the thirty sections.

   House rules honoured: Söhne throughout, 0.00em tracking, and the weight table
   (titles 600, subleaders 500, body 400, light 300). Sizes are in
   `calc(N * var(--shelfd-px, 1px))` like the rest of the app so the page scales
   with the device, and it is verified from 375pt through 440pt.
   ============================================================================= */

#profile-settings-devtools-subpage {
  /* v15.871 — TWO TEXT COLOURS, AND NO GREY.
     The page previously ran a four-step ramp (100 / 70 / 55 / 38%). Below about
     70% white on black stops reading as white and starts reading as grey, which
     is a third colour on a page whose whole brief was two. Everything secondary
     is now ONE value — white at 81% — so hierarchy comes from weight and size,
     which is where it belongs, and the page has exactly two inks. */
  /* v15.873 — CREAM, NOT WHITE. #F5F0E8 is a hair warm (245/240/232); against a
     true-black ground it reads as paper rather than as a screen, and it takes
     the hard edge off large blocks of copy without becoming a colour.

     AND REAL SURFACE STEPS. The previous cards were rgba(white, 0.028) on #000
     — a 2.8% lift, which is roughly one value step and is why sections
     dissolved into the page and into each other. Surfaces are now SOLID and
     spaced far enough apart to be told apart at a glance, each one warm-tinted
     so it sits under the cream rather than fighting it:

        ground   #000000   the page
        card     #131211   a section — clearly a plate on the ground
        raised   #201D1A   things inside a card (stat tiles, inputs, chips)

     Hairlines went 5%/8% -> 10%/14% for the same reason: at 5% a border on a
     2.8% fill is invisible, so a card had neither a surface nor an edge. */
  --dev-ink:        #F5F0E8;
  --dev-ink-soft:   rgba(245, 240, 232, 0.81);
  --dev-line:       rgba(245, 240, 232, 0.14);
  --dev-line-soft:  rgba(245, 240, 232, 0.10);
  --dev-surface:    #131211;
  --dev-surface-2:  #201D1A;
  --dev-radius:     calc(16 * var(--shelfd-px, 1px));
  --dev-font:       'Sohne', 'Söhne', 'DM Sans', system-ui, sans-serif;
  letter-spacing: 0.00em;
}/* ------------------------------------------------------------------ tabs ---
   Sticky over cards that scroll beneath, so it needs its own opaque ground —
   a transparent sticky bar smears text through itself. */


.shelfd-devtools-tabs {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  gap: calc(6 * var(--shelfd-px, 1px));
  margin: 0 0 calc(16 * var(--shelfd-px, 1px));
  padding: calc(10 * var(--shelfd-px, 1px)) 0 calc(11 * var(--shelfd-px, 1px));
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  background: #000;
  border-bottom: 1px solid var(--dev-line-soft);
}
.shelfd-devtools-tabs::-webkit-scrollbar { display: none; }

.shelfd-devtools-tab {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  padding: calc(7 * var(--shelfd-px, 1px)) calc(14 * var(--shelfd-px, 1px));
  border-radius: 999px;
  border: 1px solid var(--dev-line);
  background: transparent;
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 500;
  letter-spacing: 0.00em;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}/* Inversion, not hue: the clearest "you are here" a black-and-white page has. */

.shelfd-devtools-tab.is-active {
  background: var(--dev-ink);
  border-color: var(--dev-ink);
  color: #000;
  font-weight: 600;
}
.shelfd-devtools-tab:active { opacity: 0.7; }/* Only the active group is rendered. display:none, not visibility — a hidden
   group should cost no layout, which is most of why this page paints quickly. */


#profile-settings-devtools-subpage[data-devtab-active="tools"] .shelfd-devtools-section[data-devtab]:not([data-devtab="tools"]),
#profile-settings-devtools-subpage[data-devtab-active="users"] .shelfd-devtools-section[data-devtab]:not([data-devtab="users"]),
#profile-settings-devtools-subpage[data-devtab-active="retention"] .shelfd-devtools-section[data-devtab]:not([data-devtab="retention"]),
#profile-settings-devtools-subpage[data-devtab-active="engagement"] .shelfd-devtools-section[data-devtab]:not([data-devtab="engagement"]),
#profile-settings-devtools-subpage[data-devtab-active="health"] .shelfd-devtools-section[data-devtab]:not([data-devtab="health"]) {
  display: none;
}/* --------------------------------------------------------------- section ---
   A card is a faint plate, not an outlined box. */


.shelfd-devtools-section {
  margin: 0 0 calc(12 * var(--shelfd-px, 1px));
  padding: calc(17 * var(--shelfd-px, 1px)) calc(16 * var(--shelfd-px, 1px));
  border-radius: var(--dev-radius);
  background: var(--dev-surface);
  border: 1px solid var(--dev-line-soft);
}

.shelfd-devtools-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(10 * var(--shelfd-px, 1px));
  margin-bottom: calc(12 * var(--shelfd-px, 1px));
}
.shelfd-devtools-head strong {
  color: var(--dev-ink);
  font-family: var(--dev-font);
  font-size: max(14px, calc(15 * var(--shelfd-px, 1px)));
  font-weight: 600;
  letter-spacing: 0.00em;
}/* --------------------------------------------------------------- buttons ---
   One button treatment for the whole page. `muted` is the same shape a step
   quieter, which is all a secondary action ever needed. */


.shelfd-devtools-refresh {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  padding: calc(6 * var(--shelfd-px, 1px)) calc(13 * var(--shelfd-px, 1px));
  border-radius: 999px;
  /* v15.871: a solid white pill with a black label. The old treatment was a 5%
     fill on a 2.8% card — a button you had to look for. On a two-ink page the
     filled control is the loudest thing available, and an action should be. */
  background: var(--dev-ink);
  border: 1px solid var(--dev-ink);
  color: #000;
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 600;
  letter-spacing: 0.00em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 160ms ease;
}
.shelfd-devtools-refresh:active { opacity: 0.62; }
.shelfd-devtools-refresh:disabled { opacity: 0.4; cursor: default; }
/* Secondary keeps the silhouette and gives up the fill — same shape, clearly
   subordinate, without inventing a third colour. */
.shelfd-devtools-refresh.shelfd-devtools-muted {
  background: transparent;
  border-color: var(--dev-ink-soft);
  color: var(--dev-ink);
}/* ----------------------------------------------------------------- stats ---
   Four across at every width: the numbers are short, so fractional columns
   beat wrapping into a ragged second row. */


.shelfd-devtools-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: calc(7 * var(--shelfd-px, 1px));
}
.shelfd-devtools-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(4 * var(--shelfd-px, 1px));
  padding: calc(12 * var(--shelfd-px, 1px)) calc(4 * var(--shelfd-px, 1px));
  border-radius: calc(11 * var(--shelfd-px, 1px));
  background: var(--dev-surface-2);
  min-width: 0;
}
.shelfd-devtools-stat-num {
  color: var(--dev-ink);
  font-family: var(--dev-font);
  font-size: max(14px, calc(19 * var(--shelfd-px, 1px)));
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.shelfd-devtools-stat-label {
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
}/* ------------------------------------------------------------------ copy ---
   THE note is this window's numbers; THE desc is what they mean and never
   changes. Both are light and quiet — see point 2 in the header. */


.shelfd-devtools-note {
  margin-top: calc(11 * var(--shelfd-px, 1px));
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 300;
  line-height: 1.45;
}
.shelfd-devtools-desc {
  margin-top: calc(11 * var(--shelfd-px, 1px));
  padding-top: calc(11 * var(--shelfd-px, 1px));
  border-top: 1px solid var(--dev-line-soft);
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: 0.00em;
}
.shelfd-devtools-desc strong { color: var(--dev-ink-soft); font-weight: 500; }/* An inline button inside explainer copy gets its own line — it used to sit
   mid-sentence and broke the paragraph in half. */

.shelfd-devtools-desc .shelfd-devtools-refresh {
  display: flex;
  width: fit-content;
  margin-top: calc(11 * var(--shelfd-px, 1px));
}/* ------------------------------------------------------------- label rows --- */


.shelfd-devtools-rows {
  display: flex;
  flex-direction: column;
  gap: calc(9 * var(--shelfd-px, 1px));
}
.shelfd-devtools-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(12 * var(--shelfd-px, 1px));
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
}
.shelfd-devtools-row > span:first-child {
  color: var(--dev-ink-soft);
  font-weight: 300;
  flex: 0 0 auto;
}
.shelfd-devtools-row > span:last-child {
  color: var(--dev-ink);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}/* ----------------------------------------------------------- range chips --- */


.shelfd-devtools-range {
  display: flex;
  gap: calc(6 * var(--shelfd-px, 1px));
  margin-bottom: calc(13 * var(--shelfd-px, 1px));
}
.shelfd-devtools-range-chip {
  appearance: none;
  -webkit-appearance: none;
  flex: 1 1 0;
  padding: calc(7 * var(--shelfd-px, 1px)) calc(4 * var(--shelfd-px, 1px));
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--dev-line);
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.shelfd-devtools-range-chip.is-active {
  background: var(--dev-ink);
  border-color: var(--dev-ink);
  color: #000;
  font-weight: 500;
}/* ------------------------------------------------------------- rank rows ---
   The detail spans both columns on its own line, so a long string wraps
   instead of widening the page (v15.488). */


.shelfd-rank-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(46 * var(--shelfd-px, 1px));
  align-items: center;
  gap: calc(4 * var(--shelfd-px, 1px)) calc(9 * var(--shelfd-px, 1px));
  padding: calc(9 * var(--shelfd-px, 1px)) 0;
  border-bottom: 1px solid var(--dev-line-soft);
}
.shelfd-rank-row:last-child { border-bottom: 0; }
.shelfd-rank-label {
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  line-height: 1.3;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shelfd-rank-bar {
  display: block;
  height: calc(5 * var(--shelfd-px, 1px));
  border-radius: 999px;
  background: rgba(245, 240, 232, 0.07);
  overflow: hidden;
}/* Solid white at low opacity rather than a gradient: a two-stop gradient in one
   hue is decoration a bar chart does not need, and it read as a colour. */

.shelfd-rank-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: rgba(245, 240, 232, 0.80);
}
.shelfd-rank-detail {
  grid-column: 1 / -1;
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 300;
  line-height: 1.4;
  overflow-wrap: anywhere;
}/* The ONE place a non-white value survives: a p90 past 2s means that user felt
   a slow app, and a health page that cannot flag a bad number is decoration.
   Kept deliberately desaturated so it reads as emphasis, not as an accent. */

.shelfd-rank-detail.shelfd-perf-slow { color: rgba(245, 240, 232, 0.81); font-weight: 500; }/* --------------------------------------------------------- admin composer --- */


.shelfd-announcement-admin {
  display: flex;
  flex-direction: column;
  gap: calc(9 * var(--shelfd-px, 1px));
}
.shelfd-announcement-admin-label {
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.shelfd-announcement-admin-input,
.shelfd-announcement-admin-select,
.shelfd-announcement-admin-textarea {
  width: 100%;
  padding: calc(11 * var(--shelfd-px, 1px)) calc(12 * var(--shelfd-px, 1px));
  border-radius: calc(11 * var(--shelfd-px, 1px));
  background: var(--dev-surface-2);
  border: 1px solid var(--dev-line);
  color: var(--dev-ink);
  font-family: var(--dev-font);
  /* NO font-size here on purpose. `02-comments-login-theme.css` sets
     `input, textarea, select { font-size: calc(16 * var(--shelfd-px)) !important }`
     app-wide, so anything declared here is dead. Worth recording why that is
     FINE rather than a latent iOS bug: it computes to 13.95px at 375pt, below
     the 16px focus-auto-zoom threshold — but index.html ships
     `maximum-scale=1.0, user-scalable=no`, which suppresses focus zoom in the
     Capacitor WebView. Leaving the app-wide value in charge also keeps these
     fields identical to every other input in the app. */
  font-weight: 400;
  letter-spacing: 0.00em;
  appearance: none;
  -webkit-appearance: none;
}
.shelfd-announcement-admin-textarea { resize: vertical; line-height: 1.45; }
.shelfd-announcement-admin-input::placeholder,
.shelfd-announcement-admin-textarea::placeholder {
  color: var(--dev-ink-soft);
  font-weight: 300;
}
.shelfd-announcement-admin-input:focus,
.shelfd-announcement-admin-select:focus,
.shelfd-announcement-admin-textarea:focus {
  outline: none;
  border-color: rgba(245, 240, 232, 0.26);
  background: rgba(245, 240, 232, 0.07);
}
.shelfd-announcement-admin-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(9 * var(--shelfd-px, 1px));
}
.shelfd-announcement-admin-grid label { display: flex; flex-direction: column; gap: calc(6 * var(--shelfd-px, 1px)); min-width: 0; }
.shelfd-announcement-admin-actions {
  display: flex;
  justify-content: flex-end;
  gap: calc(8 * var(--shelfd-px, 1px));
}/* ------------------------------------------------------- recipient picker --- */


.shelfd-announcement-recipient-picker {
  display: flex;
  flex-direction: column;
  gap: calc(8 * var(--shelfd-px, 1px));
}
.shelfd-announcement-recipient-picker[hidden] { display: none; }
.shelfd-announcement-selected {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6 * var(--shelfd-px, 1px));
}
.shelfd-announcement-recipient-chip {
  display: inline-flex;
  align-items: center;
  gap: calc(6 * var(--shelfd-px, 1px));
  padding: calc(5 * var(--shelfd-px, 1px)) calc(10 * var(--shelfd-px, 1px));
  border-radius: 999px;
  background: var(--dev-surface-2);
  border: 1px solid var(--dev-line);
  min-width: 0;
}
.shelfd-announcement-recipient-chip span {
  color: var(--dev-ink-soft);
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shelfd-announcement-recipient-chip b {
  color: var(--dev-ink);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  line-height: 1;
}
.shelfd-announcement-recipient-results {
  display: flex;
  flex-direction: column;
  gap: calc(5 * var(--shelfd-px, 1px));
  max-height: calc(210 * var(--shelfd-px, 1px));
  overflow-y: auto;
}
.shelfd-announcement-recipient-result {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(9 * var(--shelfd-px, 1px));
  padding: calc(9 * var(--shelfd-px, 1px)) calc(11 * var(--shelfd-px, 1px));
  border-radius: calc(10 * var(--shelfd-px, 1px));
  background: transparent;
  border: 1px solid var(--dev-line-soft);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.shelfd-announcement-recipient-result.is-selected {
  border-color: rgba(245, 240, 232, 0.30);
  background: var(--dev-surface-2);
}
.shelfd-announcement-recipient-result span { min-width: 0; }
.shelfd-announcement-recipient-result strong,
.shelfd-announcement-recipient-result small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shelfd-announcement-recipient-result strong {
  color: var(--dev-ink);
  font-weight: 500;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: var(--dev-font);
}
.shelfd-announcement-recipient-result small,
.shelfd-announcement-recipient-note,
.shelfd-announcement-recipient-status {
  color: var(--dev-ink-soft);
  font-weight: 300;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.4;
  font-family: var(--dev-font);
}
.shelfd-announcement-recipient-result b {
  color: var(--dev-ink-soft);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1;
  font-family: var(--dev-font);
}
.shelfd-announcement-recipient-status { padding: calc(8 * var(--shelfd-px, 1px)) 0; }/* --------------------------------------------------------------- pro tag ---
   Outline only. Paid vs gifted is told by FILL, not by hue: an outlined tag is
   a paid account, a filled one was comped. */


.shelfd-devtools-pro-tag {
  display: inline-block;
  margin-left: calc(6 * var(--shelfd-px, 1px));
  padding: calc(2 * var(--shelfd-px, 1px)) calc(7 * var(--shelfd-px, 1px));
  border-radius: 999px;
  border: 1px solid rgba(167, 139, 250, 0.50);
  background: rgba(124, 92, 240, 0.18);
  color: #c4b5fd;
  font-family: var(--dev-font);
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 500;
  letter-spacing: 0.02em;
  vertical-align: middle;
  white-space: nowrap;
}
/* Gifted reads warm, paid reads lavender — a glance separates the accounts you
   comped from the ones actually paying you, which is the entire reason this tag
   exists. Hue is doing real work here, unlike the decorative purple stripped
   off the rest of the page. */
.shelfd-devtools-pro-tag.is-gifted {
  border-color: rgba(246, 191, 91, 0.50);
  background: rgba(246, 191, 91, 0.16);
  color: #f6bf5b;
}/* ------------------------------------------------------------ tight width ---
   375pt is the narrowest supported screen. The audience/expiry pair stacks
   rather than squeezing two selects into halves that truncate their own text. */


@media (max-width: 390px) {
  .shelfd-announcement-admin-grid { grid-template-columns: minmax(0, 1fr); }
  .shelfd-rank-row { grid-template-columns: minmax(0, 1fr) calc(38 * var(--shelfd-px, 1px)); }
  .shelfd-devtools-section { padding: calc(15 * var(--shelfd-px, 1px)) calc(14 * var(--shelfd-px, 1px)); }
  .shelfd-devtools-stat-label { font-size: max(14px, calc(14 * var(--shelfd-px, 1px))); }
}

@media (prefers-reduced-motion: reduce) {
  .shelfd-devtools-tab,
  .shelfd-devtools-refresh,
  .shelfd-devtools-range-chip { transition: none; }
}/* =============================================================================
   WEIGHT TIERS — and why this is the one block here that uses !important.

   44-profile-search-dm-overrides.css caps EVERY element inside #profile-page:

       #profile-page *:not(svg):not(path) { font-weight: 400 !important; }

   and then re-grants heavier weights through `:is(...)` allow-lists. The dev
   page lives inside #profile-page, so that cap flattened this entire design to
   a single weight - which is why the explainer copy read as loudly as the
   headings it sits under. An `!important` declaration cannot be answered by
   specificity, only by `!important`, so there is no cascade-free way to set a
   weight on this page; the allow-list mechanism in 44 exists precisely because
   of that.

   This is ONE block rather than an `!important` sprinkled through the file, and
   it lives with the component instead of scattering dev selectors back into the
   profile stylesheet they were just extracted from. Scoped to the dev subpage,
   so it cannot reach any user-facing surface.

   House weight table: titles 600, subleaders 500, body 400, light 300.
   ============================================================================= */


#profile-settings-devtools-subpage :is(
  .shelfd-devtools-desc,
  .shelfd-devtools-note,
  .shelfd-rank-detail,
  .shelfd-announcement-recipient-note,
  .shelfd-announcement-recipient-status,
  .shelfd-devtools-range-chip
) { font-weight: 300 !important; }

#profile-settings-devtools-subpage .shelfd-devtools-row > span:first-child { font-weight: 300 !important; }

#profile-settings-devtools-subpage :is(
  .shelfd-devtools-tab,
  .shelfd-announcement-admin-label,
  .shelfd-devtools-pro-tag,
  .shelfd-devtools-range-chip.is-active,
  .shelfd-announcement-recipient-result strong,
  .shelfd-devtools-desc strong
) { font-weight: 500 !important; }

/* v15.874: the 14px floor has to reach the form fields too.
   `02-comments-login-theme.css` sets `input, textarea, select { font-size:
   calc(16 * var(--shelfd-px)) !important }` app-wide, which lands at 13.95px on
   a 375pt screen — under the floor by a hair. An `!important` can only be
   answered by an `!important`, so this rides in the block that already carries
   that justification rather than adding a second one. */
#profile-settings-devtools-subpage :is(
  .shelfd-announcement-admin-input,
  .shelfd-announcement-admin-select,
  .shelfd-announcement-admin-textarea
) { font-size: max(14px, calc(15 * var(--shelfd-px, 1px))) !important; }

#profile-settings-devtools-subpage :is(
  .shelfd-devtools-tab.is-active,
  .shelfd-devtools-stat-num,
  .shelfd-devtools-head strong,
  .shelfd-devtools-refresh
) { font-weight: 600 !important; }/* The page's own ground. The settings surface underneath carries a faint violet
   gradient; on a black-and-white page that reads as a colour cast. */


#profile-settings-devtools-subpage { background: #000; }/* =============================================================================
   ROSTER / COHORT / ERROR / SESSION / VERSION ROWS  (moved from 37, v15.868)

   The same extraction as the rest of this file, for the class families the
   first pass missed because they are rendered by js/51 rather than written into
   index.html: shelfd-activity-*, shelfd-cal-*, shelfd-cohort-*, shelfd-error-*,
   shelfd-session-*, shelfd-signup-*, shelfd-version-*.

   Found by measuring rather than guessing - a sweep of every visible element on
   all five tabs for a computed colour whose channels were not equal turned up a
   lavender handle, an amber error kind and an amber build name still lit up on
   an otherwise black-and-white page.

   Structure is preserved verbatim; only the hues were converted. Lavender
   (196,181,253) and amber (246,191,91) both map to white at their original
   alpha, so the emphasis each one carried survives as brightness instead of as
   colour - which is exactly the substitution the rest of this page makes.
   ============================================================================= */


.shelfd-activity-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(10 * var(--shelfd-px, 1px));
  padding: calc(8 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.06);
}

.shelfd-activity-row:last-child { border-bottom: 0; }

.shelfd-activity-id { min-width: 0; flex: 1 1 auto; }

.shelfd-activity-name {
  display: block;
  color: #F5F0E8;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shelfd-activity-meta {
  display: block;
  margin-top: calc(2 * var(--shelfd-px, 1px));
  color: rgba(245, 240, 232, 0.81);
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shelfd-activity-count {
  flex: 0 0 auto;
  text-align: right;
}

.shelfd-activity-opens {
  display: block;
  color: #F5F0E8;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(15 * var(--shelfd-px, 1px)));
  font-weight: 600;
}

.shelfd-activity-opens-label {
  display: block;
  color: rgba(245, 240, 232, 0.81);
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 500;
}

.shelfd-activity-row[role="button"] { cursor: pointer; -webkit-tap-highlight-color: transparent; }

.shelfd-activity-row.is-focused { background: rgba(245, 240, 232, 0.10); }

.shelfd-signup-row {
  display: flex;
  flex-direction: column;
  gap: calc(3 * var(--shelfd-px, 1px));
  padding: calc(10 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.07);
  min-width: 0;
}

.shelfd-activity-user-link {
  display: block;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.shelfd-activity-user-link:focus-visible .shelfd-activity-name {
  color: rgba(245, 240, 232, 0.81);
}

.shelfd-activity-handle {
  display: block;
  margin-top: calc(1 * var(--shelfd-px, 1px));
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shelfd-signup-row:last-child { border-bottom: 0; }

.shelfd-signup-name {
  color: #F5F0E8;
  font-weight: 600;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-signup-handle {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-activity-user-link .shelfd-signup-handle { display: block; }

.shelfd-activity-user-link .shelfd-signup-handle { margin-top: calc(3 * var(--shelfd-px, 1px)); }

.shelfd-activity-user-link:active .shelfd-signup-name { color: rgba(245, 240, 232, 0.81); }

.shelfd-signup-detail {
  display: grid;
  grid-template-columns: calc(68 * var(--shelfd-px, 1px)) minmax(0, 1fr);
  gap: calc(7 * var(--shelfd-px, 1px));
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.35;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-signup-detail strong {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
}

.shelfd-signup-detail code {
  color: rgba(245, 240, 232, 0.81);
  font: inherit;
  overflow-wrap: anywhere;
}

.shelfd-activity-calendar { display: flex; flex-direction: column; }

.shelfd-cal-row {
  display: grid;
  grid-template-columns: calc(86 * var(--shelfd-px, 1px)) calc(46 * var(--shelfd-px, 1px)) minmax(0, 1fr);
  align-items: center;
  gap: calc(8 * var(--shelfd-px, 1px));
  padding: calc(6 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.05);
}

.shelfd-cal-row:last-child { border-bottom: 0; }

.shelfd-cal-row.is-empty { opacity: 0.42; }

.shelfd-cal-row.is-today .shelfd-cal-day { color: #F5F0E8; font-weight: 600; }

.shelfd-cal-day {
  color: rgba(245, 240, 232, 0.81);
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shelfd-cal-bar {
  display: block;
  height: calc(6 * var(--shelfd-px, 1px));
  border-radius: 999px;
  background: rgba(245, 240, 232, 0.08);
  overflow: hidden;
}

.shelfd-cal-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(245, 240, 232, 0.65), rgba(245, 240, 232, 0.95));
}

.shelfd-cal-detail {
  color: rgba(245, 240, 232, 0.81);
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  font-weight: 400;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

  .shelfd-cal-row { grid-template-columns: calc(72 * var(--shelfd-px, 1px)) calc(34 * var(--shelfd-px, 1px)) minmax(0, 1fr); }

  .shelfd-cal-day { font-size: max(14px, calc(14 * var(--shelfd-px, 1px))); }

  .shelfd-cal-detail { font-size: max(14px, calc(14 * var(--shelfd-px, 1px))); }

.shelfd-version-row {
  display: flex;
  flex-direction: column;
  gap: calc(2 * var(--shelfd-px, 1px));
  padding: calc(7 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.05);
}

.shelfd-version-row:last-child { border-bottom: 0; }

.shelfd-version-name {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-version-detail {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.3;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-variant-numeric: tabular-nums;
}

.shelfd-version-row.is-bad .shelfd-version-name { color: rgba(245, 240, 232, 0.81); }

.shelfd-version-row.is-bad .shelfd-version-detail { color: rgba(245, 240, 232, 0.81); }

.shelfd-cohort-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: calc(4 * var(--shelfd-px, 1px)) calc(8 * var(--shelfd-px, 1px));
  padding: calc(7 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.05);
}

.shelfd-cohort-row:last-child { border-bottom: 0; }

.shelfd-cohort-day {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shelfd-cohort-size {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  white-space: nowrap;
}

.shelfd-cohort-detail {
  grid-column: 1 / -1;
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.3;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  font-variant-numeric: tabular-nums;
}

.shelfd-error-row {
  display: flex;
  flex-direction: column;
  gap: calc(3 * var(--shelfd-px, 1px));
  padding: calc(9 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.07);
  min-width: 0;
}

.shelfd-error-row:last-child { border-bottom: 0; }

.shelfd-error-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(8 * var(--shelfd-px, 1px));
}

.shelfd-error-kind {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 600;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.2;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  text-transform: uppercase;
}

.shelfd-error-count {
  color: #F5F0E8;
  font-weight: 600;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.2;
  font-family: 'Sohne', 'DM Sans', sans-serif;
}

.shelfd-error-message {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.4;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-error-meta {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.35;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-session-row {
  display: flex;
  flex-direction: column;
  gap: calc(5 * var(--shelfd-px, 1px));
  padding: calc(10 * var(--shelfd-px, 1px)) 0;
  border-bottom: calc(0.9 * var(--shelfd-px, 1px)) solid rgba(245, 240, 232, 0.07);
  min-width: 0;
}

.shelfd-session-row:last-child { border-bottom: 0; }

.shelfd-session-head {
  display: flex;
  flex-direction: column;
  gap: calc(2 * var(--shelfd-px, 1px));
}

.shelfd-session-when {
  color: #F5F0E8;
  font-weight: 600;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.25;
  font-family: 'Sohne', 'DM Sans', sans-serif;
}

.shelfd-session-meta {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.35;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-session-row.is-crashed .shelfd-session-when { color: rgba(245, 240, 232, 0.81); }

.shelfd-session-error {
  display: block;
  padding: calc(5 * var(--shelfd-px, 1px)) calc(7 * var(--shelfd-px, 1px));
  border-radius: calc(7 * var(--shelfd-px, 1px));
  background: rgba(245, 240, 232, 0.1);
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.35;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  overflow-wrap: anywhere;
}

.shelfd-session-trail {
  display: flex;
  flex-wrap: wrap;
  gap: calc(4 * var(--shelfd-px, 1px));
}

.shelfd-session-event {
  display: inline-flex;
  align-items: baseline;
  gap: calc(4 * var(--shelfd-px, 1px));
  padding: calc(3 * var(--shelfd-px, 1px)) calc(6 * var(--shelfd-px, 1px));
  border-radius: calc(6 * var(--shelfd-px, 1px));
  background: rgba(245, 240, 232, 0.06);
  color: rgba(245, 240, 232, 0.81);
  font-weight: 400;
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  line-height: 1.3;
  font-family: 'Sohne', 'DM Sans', sans-serif;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.shelfd-session-time {
  color: rgba(245, 240, 232, 0.81);
  font-weight: 500;
}

/* v15.875 — NOTHING ON THIS PAGE TRUNCATES.

   At 14px these three started clipping their own content behind an ellipsis at
   375pt: the roster's meta line (25 rows), and the calendar's day and detail
   columns. Ellipsis is the right call on a consumer surface where the row is a
   target to tap; here the row IS the content, and this page exists to be read.
   The roster's own note already said as much - it was split into two lines
   precisely so the part you came to read would not be cut - and the 14px floor
   had quietly undone that. They wrap now. */
#profile-settings-devtools-subpage :is(
  .shelfd-activity-meta,
  .shelfd-cal-day,
  .shelfd-cal-detail
) {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: anywhere;
}

/* v15.876 — the page title obeys the floor too.
   `.profile-topbar-title` is the SHARED settings topbar, and at 13.08px on a
   375pt screen it was rendering SMALLER than the 14px body underneath it —
   inverted hierarchy, and the last thing on the page under the floor. Scoped to
   the dev subpage so every other settings screen keeps its own sizing. 16px
   rather than 14 so the title still leads the page it names. */
#profile-settings-devtools-subpage .profile-topbar-title {
  font-size: max(16px, calc(16 * var(--shelfd-px, 1px)));
  /* The shared topbar ships near-white (250,250,250); on this page that is the
     one element still not made of the same ink as everything under it. */
  color: var(--dev-ink);
}
#profile-settings-devtools-subpage .profile-topbar-sub {
  font-size: max(14px, calc(14 * var(--shelfd-px, 1px)));
  color: var(--dev-ink-soft);
}
