/* ============================================================================
   kid-polish.css — the CHILD dashboard's design system (2026-09-15)
   ----------------------------------------------------------------------------
   Caleb, after the deep-navy pass:
     "this card looks weird and curropted squishy and it doesnt look nice fix
      the spacing ... in fact, make sure every card is deisgned like this ...
      please use the font sohne and the clean type of font like my landing page"
     "i give you full organzier and control of creative to polish this student
      account ... i think the background and dark is nice whati got but theres
      edges and backgrouns in cards and full cotnaienrs might need a light shade"

   So: ONE card system, ONE type scale, ONE set of spacings, and a light ground
   behind the cards so the deep navy headers have something to sit on.

   TYPE — Söhne first, SF Pro behind it. The test faces live in
   fonts/soehne-test/ (gitignored, 404 on the live host), which is why the
   fallback is the same one the landing page really renders on today. Nothing
   here breaks when Söhne is absent; it simply renders in SF Pro. The day the
   Klim licence lands and the files ship, this file needs no edit.

   Söhne is a grotesque: it carries MORE presence per weight than Inter, so the
   whole scale steps DOWN a notch (Inter 800 -> Söhne 600/700). Kept as tokens
   so the next person changes the scale in one place.

   Loaded AFTER kid-theme.css so the geometry wins order-ties, while every
   colour still reads kid-theme's --kt-* tokens — the palette button keeps
   recolouring everything.
   ============================================================================ */

@font-face{ font-family:'Soehne'; src:url('../fonts/soehne-test/TestSohne-Buch.otf') format('opentype');            font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:'Soehne'; src:url('../fonts/soehne-test/TestSohne-Kraftig.otf') format('opentype');         font-weight:500; font-style:normal; font-display:swap; }
@font-face{ font-family:'Soehne'; src:url('../fonts/soehne-test/TestSohne-Halbfett.otf') format('opentype');        font-weight:600; font-style:normal; font-display:swap; }
@font-face{ font-family:'Soehne'; src:url('../fonts/soehne-test/TestSohne-Dreiviertelfett.otf') format('opentype'); font-weight:700; font-style:normal; font-display:swap; }

body.pm-tier-child{
  --kp-font: 'Soehne', -apple-system, BlinkMacSystemFont, 'SF Pro Display', system-ui, 'Inter', sans-serif;

  /* ink */
  --kp-ink:        #14181F;   /* titles */
  --kp-ink-2:      #3D4654;   /* body */
  --kp-ink-mute:   #737E8F;   /* meta, captions */

  /* surfaces — the "light shade" Caleb asked for */
  --kp-ground:     #F4F5F9;   /* behind the cards */
  --kp-card:       #FFFFFF;   /* the cards themselves */
  --kp-inset:      #F7F8FC;   /* panels inside a card (empty states, tables) */
  --kp-edge:       rgba(17, 24, 39, .08);
  --kp-edge-soft:  rgba(17, 24, 39, .05);

  /* geometry — one radius family, one padding */
  --kp-r:      18px;
  --kp-r-sm:   12px;
  --kp-pad:    20px;
  --kp-shadow:
     0 1px 2px rgba(16, 24, 40, .04),
     0 12px 28px -18px rgba(16, 24, 40, .22);
  --kp-shadow-lift:
     0 2px 4px rgba(16, 24, 40, .05),
     0 20px 40px -20px rgba(16, 24, 40, .28);
}

/* ── 1) TYPE ───────────────────────────────────────────────────────────────
   One family across the whole child surface; weights step down for Söhne. */
body.pm-tier-child #pmChildHero,
body.pm-tier-child #pmChildHero button,
body.pm-tier-child #pmChildHero input,
body.pm-tier-child #pmChildHero select{ font-family: var(--kp-font); }

body.pm-tier-child .pmch-greet h2{
  font: 700 27px/1.15 var(--kp-font) !important;
  letter-spacing: -0.021em !important;
}
body.pm-tier-child .pmch-greet p{
  font: 450 13.5px/1.5 var(--kp-font) !important;
  letter-spacing: -0.003em !important;
}
/* every card title, one size */
body.pm-tier-child .pmch-sessions__title,
body.pm-tier-child .pmch-homework__title,
body.pm-tier-child .pmch-video-title,
body.pm-tier-child .pmch-playlist__title{
  font: 600 16.5px/1.25 var(--kp-font) !important;
  letter-spacing: -0.012em !important;
}
/* every small uppercase label, one size */
body.pm-tier-child .pmch-sessions__table th,
body.pm-tier-child .ktd-bodyhead__today,
body.pm-tier-child .ktd-pill{
  font: 600 10.5px/1 var(--kp-font) !important;
  letter-spacing: .085em !important;
  text-transform: uppercase !important;
}
body.pm-tier-child .pmch-sessions__table td{
  font: 450 13.5px/1.45 var(--kp-font) !important;
  color: var(--kp-ink-2) !important;
  letter-spacing: -0.003em !important;
}
/* the clock keeps its presence but loses Inter's extra weight */
body.pm-tier-child .ktd-hero__time{
  font: 700 38px/1 var(--kp-font) !important;
  letter-spacing: -0.028em !important;
}
body.pm-tier-child .ktd-hero__date{
  font: 500 12.5px/1 var(--kp-font) !important;
  letter-spacing: .01em !important;
}

/* ── 2) THE GROUND — a light shade so the navy headers have a floor ──────── */
body.pm-tier-child .pmch-shell{
  background: var(--kp-ground) !important;
  border-radius: 26px;
}

/* ── 3) ONE CARD ──────────────────────────────────────────────────────────
   Same edge, same radius, same shadow, same padding — everywhere. */
body.pm-tier-child .ktd-card,
body.pm-tier-child .pmch-sessions,
body.pm-tier-child .pmch-homework,
body.pm-tier-child .pmch-video-card,
body.pm-tier-child .pmch-playlist{
  background: var(--kp-card) !important;
  border: 1px solid var(--kp-edge) !important;
  border-radius: var(--kp-r) !important;
  box-shadow: var(--kp-shadow) !important;
}
/* overflow:hidden ONLY where a deep header bar must meet the radius.
   NEVER on .pmch-video-card: it holds the YouTube <iframe>, and a CLIPPED
   IFRAME CANNOT SCROLL ON THE COMPOSITOR'S FAST PATH — it falls back to the
   main thread and the whole page stutters. I introduced exactly that bug
   earlier today; this comment is here so nobody re-adds it. Same lesson as
   the hiring-pipeline document panel. */
body.pm-tier-child .ktd-card,
body.pm-tier-child .pmch-sessions,
body.pm-tier-child .pmch-homework{ overflow: hidden !important; }
body.pm-tier-child .ktd-card:hover,
body.pm-tier-child .pmch-sessions:hover,
body.pm-tier-child .pmch-homework:hover,
body.pm-tier-child .pmch-video-card:hover{
  box-shadow: var(--kp-shadow-lift) !important;
}
/* the diagonal "sheen" sweep belonged to the old candy look — it read as a
   smear over the new flat cards. */
body.pm-tier-child .pmch-video-card::after,
body.pm-tier-child .pmch-playlist::after,
body.pm-tier-child .pmch-homework::after{ content: none !important; }

/* ── 4) THE TODAY CARD — the squishy one ──────────────────────────────────
   It was padded 14/16 while every neighbour used 20, the head sat on 2px, and
   the reminder block was injected with a 12px inline margin against a body
   that ended 16px from the card edge. Everything below is one rhythm. */
body.pm-tier-child .ktd-hero{ padding: 22px var(--kp-pad) 20px !important; }
body.pm-tier-child .ktd-body{
  background: var(--kp-card) !important;
  padding: 18px var(--kp-pad) var(--kp-pad) !important;
}
body.pm-tier-child .ktd-bodyhead{
  padding: 0 0 14px !important;
  margin: 0 0 2px !important;
  border-bottom: 1px solid var(--kp-edge-soft);
}
body.pm-tier-child .ktd-bodyhead__today{ color: var(--kp-ink-mute) !important; }
body.pm-tier-child .ktd-pill{
  background: color-mix(in srgb, var(--kt-accent-bright) 12%, transparent) !important;
  border-color: color-mix(in srgb, var(--kt-accent-bright) 22%, transparent) !important;
  color: var(--kt-accent-deep) !important;
  padding: 6px 12px !important;
}
body.pm-tier-child .ktd-list{ gap: 10px !important; padding-top: 14px !important; }
body.pm-tier-child .ktd-card .pmch-today-row{
  border-radius: var(--kp-r-sm) !important;
  padding: 15px 16px !important;
  align-items: center !important;
}
body.pm-tier-child .pmch-today-row__title{
  font: 600 16px/1.25 var(--kp-font) !important; letter-spacing: -0.012em !important;
  margin: 3px 0 0 !important;
}
body.pm-tier-child .pmch-today-row__time{
  font: 500 12.5px/1.3 var(--kp-font) !important; letter-spacing: -0.002em !important;
}
body.pm-tier-child .pmch-today-row__meta{
  font: 450 12px/1.3 var(--kp-font) !important; margin: 4px 0 0 !important;
}
body.pm-tier-child .pmch-today-row__cta{
  font: 600 12.5px/1 var(--kp-font) !important;
  border-radius: 999px !important; padding: 9px 16px !important;
  white-space: nowrap;
}
/* the reminder block — given room, and a quiet inset instead of a loud button */
/* card.appendChild(wrap) puts this OUTSIDE .ktd-body, so it inherits none of
   the body's padding — which is why it sat flush against the card edge and
   looked like it was falling out of the box. Give it the body's own rhythm
   and pull the body's bottom padding in so the two do not double up. */
body.pm-tier-child #pmchRemindWrap{
  margin: 0 !important;
  padding: 0 var(--kp-pad) var(--kp-pad) !important;
  background: var(--kp-card) !important;
}
body.pm-tier-child .ktd-card:has(#pmchRemindWrap) .ktd-body{ padding-bottom: 16px !important; }
/* The reminder button. Caleb: "this button is weak and looks cheap ... make
   this much more preimum like the premium buttons i have on landing page", then
   "jsut connect it to the colour them and it shoul match in a light ightler".
   So: presence comes from CRAFT, not from weight — a crisp edge, a real shadow,
   a proper icon chip and confident spacing, all in a LIGHT wash of whatever
   theme the child is wearing. The emoji is gone; the bell is a stroked SVG that
   renders identically on every OS. */
body.pm-tier-child #pmchRemindBtn{
  position: relative !important; isolation: isolate !important;
  display: inline-flex !important; align-items: center !important; gap: 11px !important;
  font: 600 13.5px/1 var(--kp-font) !important;
  letter-spacing: -0.006em !important;
  color: #FFFFFF !important;
  background: var(--kt-primary-grad) !important;
  border: 1px solid color-mix(in srgb, #FFFFFF 26%, transparent) !important;
  border-radius: 13px !important;
  padding: 11px 18px 11px 11px !important;
  cursor: pointer !important;
  box-shadow:
    0 1px 2px rgba(16,24,40,.10),
    0 14px 26px -16px color-mix(in srgb, var(--kt-chrome-deep) 85%, transparent) !important;
  transition: transform .18s cubic-bezier(.34,1.56,.64,1), box-shadow .18s ease !important;
}

/* The icon sits in its own chip, the way a premium control carries its glyph.
   2026-09-15 — Caleb supplied assets/images/bell.png: a 512x512 BLACK outlined
   bell on transparency. Black on a coloured chip would be invisible, so
   `brightness(0) invert(1)` renders it pure white regardless of the source
   colour — the chip stays themed and the bell always reads. The box-sizing line
   is load-bearing: without it the padding would be ADDED to the 30px and the
   chip would grow. */
body.pm-tier-child #pmchRemindBtn .pmch-remind__chip{
  box-sizing: border-box !important;
  width: 32px !important; height: 32px !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  border-radius: 10px !important;
  background: var(--kt-primary-grad) !important;
  box-shadow: 0 4px 10px -6px color-mix(in srgb, var(--kt-chrome-deep) 75%, transparent) !important;
  flex: 0 0 auto !important;
}
/* The chip carries the COLOUR, the image carries the FILTER. They must be two
   elements: `filter` applies to the whole element including its own background,
   so putting brightness(0) invert(1) on an <img> that also had the gradient
   turned the entire chip white — which is exactly what Caleb saw. */
body.pm-tier-child #pmchRemindBtn .pmch-remind__icon{
  width: 18px !important; height: 18px !important;
  display: block !important; object-fit: contain !important;
  filter: brightness(0) invert(1) !important;   /* black artwork -> white glyph */
}
body.pm-tier-child #pmchRemindBtn:hover{
  transform: translateY(-1px) !important;
  border-color: color-mix(in srgb, var(--kt-accent-bright) 48%, transparent) !important;
  box-shadow:
    0 2px 4px rgba(16,24,40,.06),
    0 16px 28px -16px color-mix(in srgb, var(--kt-chrome-deep) 70%, transparent) !important;
}
body.pm-tier-child #pmchRemindBtn:active{ transform: translateY(0) !important; }
body.pm-tier-child #pmchRemindBtn:focus-visible{
  outline: 2px solid var(--kt-accent-bright) !important; outline-offset: 2px !important;
}
body.pm-tier-child #pmchRemindBtn[disabled]{ opacity:.6 !important; cursor: default !important; transform:none !important; }
/* DIRECT child only: `#pmchRemindWrap span` also matched the button's own label
   and icon chip, which is why the caption looked as heavy as the button text.
   Caleb: "this is too bold ... it should read like fine print". */
body.pm-tier-child #pmchRemindWrap > span{
  font: 400 11.5px/1.55 var(--kp-font) !important;
  letter-spacing: 0 !important;
  color: #8A94A6 !important;
  margin-top: 10px !important;
  max-width: 46ch;
}

/* ── 5) MY SESSIONS — the table reads like data, not decoration ──────────── */
body.pm-tier-child .pmch-sessions__table th{
  background: var(--kp-inset) !important;
  color: var(--kp-ink-mute) !important;
  border-bottom: 1px solid var(--kp-edge) !important;
  padding: 11px var(--kp-pad) !important;
}
body.pm-tier-child .pmch-sessions__table td{
  padding: 13px var(--kp-pad) !important;
  border-bottom: 1px solid var(--kp-edge-soft) !important;
}
body.pm-tier-child .pmch-sessions__table tr:hover td{ background: #FAFBFE !important; }
body.pm-tier-child .pmch-sessions__table tr:last-child td{ border-bottom: 0 !important; }
/* status pills: quiet by default, the theme colour only for what is NEXT */
body.pm-tier-child .pmch-pill-status{
  font: 600 10px/1 var(--kp-font) !important;
  letter-spacing: .07em !important;
  min-width: 86px !important; padding: 6px 12px !important;
  border: 1px solid transparent;
}
body.pm-tier-child .pmch-pill-status--upcoming{
  background: var(--kp-inset) !important; color: var(--kp-ink-mute) !important;
  border-color: var(--kp-edge) !important;
}
body.pm-tier-child .pmch-pill-status--next{
  background: var(--kt-primary-grad) !important; color:#fff !important;
  border-color: transparent !important; animation: none !important;  /* the pulse read as a glitch beside flat cards */
  box-shadow: 0 6px 14px -8px color-mix(in srgb, var(--kt-chrome-deep) 80%, transparent) !important;
}
body.pm-tier-child .pmch-pill-status--done{ background:#ECFDF5 !important; color:#047857 !important; border-color:#A7F3D0 !important; }
body.pm-tier-child .pmch-pill-status--cancel{ background:#FEF2F2 !important; color:#B91C1C !important; border-color:#FECACA !important; }
body.pm-tier-child .pmch-pill-status--miss{ background:#FFFBEB !important; color:#B45309 !important; border-color:#FDE68A !important; }

/* ── 6) MY WORK — the empty state gets a proper inset ────────────────────── */
body.pm-tier-child .pmch-homework{ padding: var(--kp-pad) !important; }
body.pm-tier-child .pmch-homework__list{ gap: 10px !important; }
body.pm-tier-child .pmch-homework__empty,
body.pm-tier-child .pmch-homework__list > div[style*="text-align"]{
  background: var(--kp-inset) !important;
  border: 1px solid var(--kp-edge-soft) !important;
  border-radius: var(--kp-r-sm) !important;
}

/* ── 7) SUBJECT TILES — same geometry as the cards; colour kept (it is a
   child's page), but the type follows the system and the edges match. ────── */
body.pm-tier-child .pmch-subj{
  border-radius: var(--kp-r) !important;
  box-shadow: var(--kp-shadow) !important;
}
body.pm-tier-child .pmch-subj:hover{ box-shadow: var(--kp-shadow-lift) !important; }
body.pm-tier-child .pmch-subj__meta-label,
body.pm-tier-child .pmch-subj__eyebrow{
  font: 600 10.5px/1 var(--kp-font) !important; letter-spacing: .085em !important;
}
body.pm-tier-child .pmch-subj__name{
  font: 600 19px/1.2 var(--kp-font) !important; letter-spacing: -0.015em !important;
}

/* ── 8) Reduced motion: the page should be calm for anyone who asks. ─────── */
@media (prefers-reduced-motion: reduce){
  body.pm-tier-child .pmch-mascot{ animation: none !important; }
  body.pm-tier-child .ktd-card,
  body.pm-tier-child .pmch-sessions,
  body.pm-tier-child .pmch-homework{ transition: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   9) SCROLL PERFORMANCE (Caleb: "this page is very laggy when i scroll i want
      it cocmpeltely smooth")

   Audited every perpetual animation and every blurred surface on this page.
   The rule the browser follows: TRANSFORM and OPACITY are handed to the GPU;
   everything else (background-position, left/top, box-shadow, backdrop-filter)
   is repainted — or re-laid-out — on the main thread, every single frame,
   forever, whether or not the element is on screen. Four things here were
   paying that cost during every scroll.
   ══════════════════════════════════════════════════════════════════════════ */

/* (a) THE BIGGEST ONE — a FIXED element with a backdrop-filter forces the
   browser to re-blur what is behind it on every scroll frame. The toast is
   already 94% opaque white, so the blur was invisible and the cost was total. */
body.pm-tier-child .pmch-worktoast{
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  background: rgba(255,255,255,.98) !important;
}

/* 2026-09-15 — Caleb: "invisible backgorund make it so its not see through".
   The card was rendering with NO background at all on the real page, so its
   text sat straight on top of the "My work" card behind it, and the wrapped
   lines spilled past the bottom edge. Rather than keep chasing which sheet was
   winning the cascade, this block states the whole card outright at a
   specificity nothing else on the page reaches (html + body + class), and uses
   the LONGHAND background-color, which cannot be silently dropped the way a
   `background:` shorthand can when another rule sets only part of it. */
html body.pm-tier-child .pmch-worktoast{
  background-color: #FFFFFF !important;   /* fully opaque — never see-through */
  background-image: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;

  /* let it size to its content so wrapped text can never spill out */
  width: min(360px, calc(100vw - 32px)) !important;
  height: auto !important;
  min-height: 0 !important;
  max-height: none !important;
  align-items: center !important;
  gap: 13px !important;
  padding: 16px 16px 16px 15px !important;
  overflow: visible !important;

  border: 1px solid var(--kp-edge, rgba(17,24,39,.08)) !important;
  border-radius: var(--kp-r, 18px) !important;
  box-shadow: 0 2px 6px rgba(16,24,40,.06), 0 24px 48px -20px rgba(16,24,40,.34) !important;
  font-family: var(--kp-font) !important;
}
/* the text column takes the room it needs and wraps inside the card */
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__body{
  flex: 1 1 auto !important;
  min-width: 0 !important;
}
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__title{
  font: 600 14px/1.3 var(--kp-font) !important;
  letter-spacing: -.012em !important;
  color: var(--kp-ink, #14181F) !important;
}
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__title b{
  font-weight: 700 !important;
  color: var(--kt-accent-deep, #0D5C58) !important;
}
/* fine print, the way Caleb asked for the reminder line */
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__sub{
  margin: 3px 0 0 !important;
  font: 400 12px/1.4 var(--kp-font) !important;
  color: var(--kp-ink-mute, #737E8F) !important;
}
/* the two controls keep their own size so the text cannot squeeze them away */
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__cta{
  flex: 0 0 auto !important;
  white-space: nowrap !important;
}
/* the dismiss sits in the corner instead of stealing a column from the text */
html body.pm-tier-child .pmch-worktoast .pmch-worktoast__close{
  position: absolute !important;
  top: 6px !important;
  right: 6px !important;
  background: transparent !important;
  border: 0 !important;
}
html body.pm-tier-child .pmch-worktoast{ position: fixed !important; }

/* (b) THE ONE THAT MATTERED — body.pm-tier-child::after is position:FIXED,
   inset:0 (the whole viewport), paints TEN radial gradients, and animated
   background-position on a 30s loop, forever. A full-viewport fixed layer
   repainting every frame saturates the main thread, and scroll input then waits
   for it — which is exactly the "doesn't move for a quarter second" Caleb
   described. ::before is the same size (five more gradients), static.

   Both are now (1) still, and (2) promoted to their own GPU layer, so they are
   painted ONCE and the compositor scrolls the page without touching them again.

   NOTE FOR NEXT TIME: my first attempt guessed at `.pmch-stars` and friends and
   hit NOTHING, which is why the lag survived it. These selectors were extracted
   from the page's real CSS, not imagined. */
body.pm-tier-child::before,
body.pm-tier-child::after{
  animation: none !important;
  transform: translateZ(0);
  backface-visibility: hidden;
  will-change: transform;
}

/* (b2) Everything else on this page that animates a NON-COMPOSITED property
   forever. Each selector below was read out of the page's own stylesheet.
   background-position and left/top repaint or re-lay-out the element on every
   frame; box-shadow repaints it. None of these carry meaning — they are glow,
   sheen and shimmer. The mascot bob and the live-session cues are transform and
   opacity, so they cost nothing and are deliberately kept. */
body.pm-tier-child .pmch-grid::before,          /* background-position */
body.pm-tier-child .pmch-grid::after,           /* background-position */
body.pm-tier-child .pmch-hw--next::before,      /* background-position */
body.pm-tier-child .pmch-crewbar__shimmer::before, /* left  (layout!) */
body.pm-tier-child .pmch-cloud--1,              /* left  (layout!) */
body.pm-tier-child .pmch-cloud--2,              /* left  (layout!) */
body.pm-tier-child .pmch-crew__cloud--1,
body.pm-tier-child .pmch-crew__cloud--2,
body.pm-tier-child .pmch-crew__cloud--3,
body.pm-tier-child .pmch-divider__badge,        /* box-shadow */
body.pm-tier-child .pmch-crewbar,               /* box-shadow */
body.pm-tier-child .pmch-hw--next,              /* box-shadow */
body.pm-tier-child .pmch-crewbar__star,
body.pm-tier-child .pmch-steve,
body.pm-tier-child .ktd-card[data-state="soon"] .pmch-today-row__time::before, /* box-shadow */
body.pm-tier-child .pmch-cit-sun,               /* the citadel scene: ambient only */
body.pm-tier-child .pmch-cit-star,
body.pm-tier-child .pmch-cit-float,
body.pm-tier-child .pmch-cit-puff,
body.pm-tier-child .pmch-citadel__hud-dot,
body.pm-tier-child .pmch-crew__sun{
  animation: none !important;
}

/* (b3) Two blurred surfaces that are NOT the toast. A backdrop-filter inside a
   scrolling page re-blurs whatever is behind it as the page moves. */
body.pm-tier-child .pmch-citadel__hud,
body.pm-tier-child .pmch-cit-badge{
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* (c) The cloud keyframes are left transform-based in case anyone re-enables
   them: if the drift ever comes back, it comes back on the GPU, not on left. */
@keyframes pmchCloudDrift{
  0%   { transform: translate3d(-40px, 0, 0); }
  100% { transform: translate3d(calc(100vw + 40px), 0, 0); }
}
body.pm-tier-child .pmch-cloud--1,
body.pm-tier-child .pmch-cloud--2{ left: 0 !important; will-change: transform; }

/* (d) — folded into (b2) above with the REAL selectors. The guesses that used
   to live here (.pmch-badge, .ktd-soon) matched no element on this page. */

/* (e) The mascot bob is transform-only (GPU, cheap) and stays — it is the one
   piece of motion a child's page should keep. */

/* The confirmed state: same control, quietly done. */
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn{
  background: linear-gradient(180deg, #FFFFFF 0%,
              color-mix(in srgb, var(--kt-accent-bright) 10%, #FFFFFF) 100%) !important;
  border-color: color-mix(in srgb, var(--kt-accent-bright) 40%, transparent) !important;
  opacity: 1 !important; cursor: default !important;
}
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn:hover{ transform: none !important; }

/* ══════════════════════════════════════════════════════════════════════════
   The reminder button, made to be clicked (Caleb: "why note just make it all
   coloru theme ... also add glow and sprakles and vibration or soemthing so it
   gets them to click it").

   Every animation below moves only TRANSFORM or OPACITY. That is the whole
   discipline: those two are handed to the GPU, so a button that glows, sparkles
   and rings costs the scroll nothing — unlike the box-shadow and
   background-position pulses removed earlier today. Nothing here animates a
   property that repaints.
   ══════════════════════════════════════════════════════════════════════════ */

/* the glow — a blurred copy of the button sitting behind it, breathing */
body.pm-tier-child #pmchRemindBtn::before{
  content:'';
  position:absolute; inset:-7px;
  border-radius:19px;
  background: var(--kt-primary-grad);
  filter: blur(13px);              /* painted once; only opacity animates */
  opacity:.42;
  z-index:-1;
  animation: pmRemindGlow 2.6s ease-in-out infinite;
  pointer-events:none;
}
@keyframes pmRemindGlow{
  0%,100%{ opacity:.34; transform:scale(.985); }
  50%    { opacity:.72; transform:scale(1.015); }
}

/* the sparkles — three small glints drifting across the face */
body.pm-tier-child #pmchRemindBtn::after{
  content:'';
  position:absolute; inset:0;
  border-radius:12px;
  pointer-events:none;
  background-image:
    radial-gradient(circle at 22% 32%, rgba(255,255,255,.95) 0, rgba(255,255,255,0) 1.7px),
    radial-gradient(circle at 68% 24%, rgba(255,255,255,.85) 0, rgba(255,255,255,0) 1.4px),
    radial-gradient(circle at 84% 72%, rgba(255,255,255,.9)  0, rgba(255,255,255,0) 1.6px);
  opacity:0;
  animation: pmRemindSparkle 3.4s ease-in-out infinite;
}
@keyframes pmRemindSparkle{
  0%, 62%, 100% { opacity:0;   transform: translate3d(0,0,0) scale(1); }
  70%           { opacity:.95; transform: translate3d(0,-1px,0) scale(1.04); }
  84%           { opacity:.35; transform: translate3d(0,-2px,0) scale(1.02); }
}

/* the bell rings — a short shake every few seconds, then rests */
body.pm-tier-child #pmchRemindBtn .pmch-remind__chip{
  background: rgba(255,255,255,.18) !important;
  border: 1px solid rgba(255,255,255,.30) !important;
  box-shadow: none !important;
}
body.pm-tier-child #pmchRemindBtn .pmch-remind__icon{
  transform-origin: 50% 18%;                 /* swings from the crown, like a bell */
  animation: pmRemindRing 3.4s ease-in-out infinite;
}
@keyframes pmRemindRing{
  0%, 70%, 100% { transform: rotate(0deg); }
  73%  { transform: rotate(15deg); }
  77%  { transform: rotate(-12deg); }
  81%  { transform: rotate(8deg); }
  85%  { transform: rotate(-5deg); }
  89%  { transform: rotate(0deg); }
}

body.pm-tier-child #pmchRemindBtn:hover{
  transform: translateY(-1px) !important;
  box-shadow:
    0 2px 4px rgba(16,24,40,.12),
    0 20px 34px -18px color-mix(in srgb, var(--kt-chrome-deep) 85%, transparent) !important;
}
body.pm-tier-child #pmchRemindBtn:hover::before{ opacity:.85; }
body.pm-tier-child #pmchRemindBtn:active{ transform: translateY(0) scale(.985) !important; }

/* Once reminders are ON the button has nothing left to sell: it goes quiet —
   no glow, no sparkle, no ring — and simply confirms. */
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn::before,
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn::after{ animation:none !important; opacity:0 !important; }
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn .pmch-remind__icon{ animation:none !important; }
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn{
  background: color-mix(in srgb, var(--kt-accent-bright) 14%, #FFFFFF) !important;
  color:#14181F !important;
  border-color: color-mix(in srgb, var(--kt-accent-bright) 38%, transparent) !important;
  box-shadow: 0 1px 2px rgba(16,24,40,.05) !important;
  cursor: default !important;
}
body.pm-tier-child #pmchRemindWrap.is-on #pmchRemindBtn .pmch-remind__chip{
  background: var(--kt-primary-grad) !important; border-color: transparent !important;
}

/* A child who asked their system for less motion gets a still button that still
   looks finished — colour and depth stay, only the movement goes. */
@media (prefers-reduced-motion: reduce){
  body.pm-tier-child #pmchRemindBtn::before,
  body.pm-tier-child #pmchRemindBtn::after,
  body.pm-tier-child #pmchRemindBtn .pmch-remind__icon{ animation: none !important; }
  body.pm-tier-child #pmchRemindBtn::before{ opacity:.5; }
}

/* ══════════════════════════════════════════════════════════════════════════
   10) Details Caleb caught at 4x zoom (2026-09-15)

   "the green notiefcation looks cheap ... the 0 isnt even in the middle of the
    curcle ... the boarder looks too big"
   "why is the end of the pill and the button green look like dark marks on the end"
   "the pull down thing and right sdie of the bill menu there, its not fully green"

   All three were the same class of bug: hard-coded colours from the old purple
   era left inside elements that the theme now paints, plus one box-model slip.
   ══════════════════════════════════════════════════════════════════════════ */

/* (a) THE COUNT BADGE. The "0" sat high because the circle was height:18px with
   a 2px border and NO box-sizing — so the box is really 22px tall while
   line-height centred the digit for 18px. Centring by line-height is the bug;
   flex centring cannot drift. The ring is thinner, the gradient is gone (a
   gradient across 20px just muddies it), and the colour now comes from the
   theme instead of a fixed green. */
body.pm-tier-child .pmch-pill__badge{
  box-sizing: border-box !important;
  top: -3px !important; right: -3px !important;
  min-width: 20px !important; height: 20px !important; padding: 0 5px !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  font: 700 11px/1 var(--kp-font) !important;      /* line-height 1 — flex does the centring */
  letter-spacing: -0.01em !important;
  background: var(--kt-chrome-deep) !important;    /* reads on any theme's pill */
  color: #FFFFFF !important;
  border: 1.5px solid #FFFFFF !important;
  box-shadow: 0 2px 6px -1px rgba(16,24,40,.35) !important;
}

/* (b) THE DARK MARKS. The crew bar still carried the old purple drop shadows
   (rgba(124,58,237,…)) and a black inset rule. A purple shadow under a teal bar
   is not a shadow, it is a dirty smear — which is exactly what the zoom shows.
   Shadows now derive from the theme's own deep tone, and the black inset goes. */
body.pm-tier-child .pmch-crewbar{
  border-color: color-mix(in srgb, #FFFFFF 26%, transparent) !important;
  box-shadow:
    0 12px 26px -14px color-mix(in srgb, var(--kt-chrome-deep) 70%, transparent),
    inset 0 1px 0 rgba(255,255,255,.28) !important;
}

/* (c) THE PILL'S RIGHT END. .pmch-pill--watched kept a fixed green ink
   (#047857) from when the pill was light; on the deep pill it read as a
   different, duller patch at the end of the row. It is simply one of the icons
   now — white, like its neighbours. */
body.pm-tier-child .pmch-pill--watched,
body.pm-tier-child .pmch-pill--watched:hover{ color:#FFFFFF !important; }

/* the hover label under these icons was purple-on-purple from the same era */
body.pm-tier-child .pmch-pill__tip{
  background: var(--kt-chrome-deep) !important;
  box-shadow: 0 6px 14px -4px rgba(16,24,40,.45) !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   11) THE LEGACY PURPLE EDGE SWEEP (2026-09-15)

   Caleb kept finding "dark marks" and "dark spots on the edge" — on the crew
   bar, the icon pill, the video strips, the card corners. Each time I fixed the
   one element he pointed at. That was the wrong unit of work.

   The real cause: this dashboard was purple before it was themed. 53 rules
   still carry a PURPLE border or a PURPLE/BLACK shadow
   (rgba(124,58,237), rgba(168,85,247), rgba(217,70,239), rgba(244,114,182)…).
   A purple shadow under a teal surface does not read as a shadow — it reads as
   a dirty smear, which is exactly what the 4x zooms showed.

   Every one of those selectors is re-edged here, in one place, from theme
   tokens. Borders only — geometry, radius and layout are untouched, so nothing
   moves; only the colour of the edge changes, and it now follows the palette.
   ══════════════════════════════════════════════════════════════════════════ */
body.pm-tier-child .ktd-card,
body.pm-tier-child .ktd-card .pmch-today-row,
body.pm-tier-child .ktd-card .pmch-today-row.is-live,
body.pm-tier-child .ktd-card .pmch-today-row.is-live .pmch-today-row__cta,
body.pm-tier-child .ktd-card .pmch-today-row.is-live .pmch-today-row__cta:hover,
body.pm-tier-child .ktd-card .pmch-today-row.is-live .pmch-today-row__time::before,
body.pm-tier-child .ktd-card .pmch-today-row__cta,
body.pm-tier-child .ktd-card .pmch-today-row__time::before,
body.pm-tier-child .ktd-card:hover,
body.pm-tier-child .ktd-card[data-state="live"],
body.pm-tier-child .ktd-card[data-state="live"] .pmch-today-row,
body.pm-tier-child .ktd-card[data-state="live"] .pmch-today-row__cta,
body.pm-tier-child .ktd-card[data-state="live"] .pmch-today-row__cta:hover,
body.pm-tier-child .ktd-card[data-state="live"] .pmch-today-row__time::before,
body.pm-tier-child .ktd-hero,
body.pm-tier-child .ktd-pill,
body.pm-tier-child .pmch-cit-badge,
body.pm-tier-child .pmch-cit-badge:hover,
body.pm-tier-child .pmch-cit-puff--2,
body.pm-tier-child .pmch-citadel__world,
body.pm-tier-child .pmch-crew__scene,
body.pm-tier-child .pmch-crewbar,
body.pm-tier-child .pmch-divider__badge,
body.pm-tier-child .pmch-grid > .pmch-video-card,
body.pm-tier-child .pmch-grid::after,
body.pm-tier-child .pmch-grid::before,
body.pm-tier-child .pmch-homework,
body.pm-tier-child .pmch-homework:hover,
body.pm-tier-child .pmch-homework__title::before,
body.pm-tier-child .pmch-icons,
body.pm-tier-child .pmch-item.is-active,
body.pm-tier-child .pmch-item:hover,
body.pm-tier-child .pmch-mark-btn,
body.pm-tier-child .pmch-mark-btn:hover,
body.pm-tier-child .pmch-pill:hover,
body.pm-tier-child .pmch-pill__tip,
body.pm-tier-child .pmch-playlist,
body.pm-tier-child .pmch-playlist:hover,
body.pm-tier-child .pmch-playlist__count,
body.pm-tier-child .pmch-playlist__list > .pmch-item.is-active:hover,
body.pm-tier-child .pmch-playlist__title::before,
body.pm-tier-child .pmch-quicklearn--crew .pmch-crew__scene,
body.pm-tier-child .pmch-section__link,
body.pm-tier-child .pmch-section__link:hover,
body.pm-tier-child .pmch-section__title::before,
body.pm-tier-child .pmch-sessions,
body.pm-tier-child .pmch-sessions:hover,
body.pm-tier-child .pmch-sessions__head,
body.pm-tier-child .pmch-sessions__table td,
body.pm-tier-child .pmch-sessions__table th,
body.pm-tier-child .pmch-sessions__title::before,
body.pm-tier-child .pmch-shell,
body.pm-tier-child .pmch-subj,
body.pm-tier-child .pmch-subj--english,
body.pm-tier-child .pmch-today,
body.pm-tier-child .pmch-today__dot,
body.pm-tier-child .pmch-topbar,
body.pm-tier-child .pmch-video-card,
body.pm-tier-child .pmch-video-card:hover,
body.pm-tier-child .pmch-video-wrap,
body.pm-tier-child .pmch-watched,
body.pm-tier-child .pmch-watched__head:hover{
  border-color: color-mix(in srgb, var(--kt-accent-bright) 26%, transparent) !important;
}

/* The decorative strips at the top and bottom of the video grid: purple border,
   purple glow AND a black inset rule. On teal that black line is the "dark spot
   on the corner". Re-edged and re-shadowed from the theme; the inset black goes. */
body.pm-tier-child .pmch-grid::before,
body.pm-tier-child .pmch-grid::after{
  border-color: color-mix(in srgb, #FFFFFF 26%, transparent) !important;
  box-shadow: none !important;
}
body.pm-tier-child .pmch-grid::before{ border-bottom-color: rgba(255,255,255,.30) !important; }
body.pm-tier-child .pmch-grid::after{ border-top-color: rgba(255,255,255,.30) !important; }

/* The surfaces keep a real shadow — but cast in the theme's own deep tone
   rather than in violet. */
body.pm-tier-child .pmch-video-card,
body.pm-tier-child .pmch-playlist,
body.pm-tier-child .pmch-sessions,
body.pm-tier-child .pmch-homework,
body.pm-tier-child .ktd-card{
  box-shadow:
    0 1px 2px rgba(16,24,40,.04),
    0 12px 28px -18px color-mix(in srgb, var(--kt-chrome-deep) 55%, transparent) !important;
}
body.pm-tier-child .pmch-video-card:hover,
body.pm-tier-child .pmch-playlist:hover,
body.pm-tier-child .pmch-sessions:hover,
body.pm-tier-child .pmch-homework:hover,
body.pm-tier-child .ktd-card:hover{
  box-shadow:
    0 2px 4px rgba(16,24,40,.05),
    0 20px 40px -20px color-mix(in srgb, var(--kt-chrome-deep) 62%, transparent) !important;
}

/* Playlist rows: the active/hover state was a violet wash on a teal card. */
body.pm-tier-child .pmch-item:hover,
body.pm-tier-child .pmch-item.is-active{
  background: color-mix(in srgb, var(--kt-accent-bright) 10%, #FFFFFF) !important;
  border-color: color-mix(in srgb, var(--kt-accent-bright) 34%, transparent) !important;
  box-shadow: none !important;
}

/* ── 12) Playlist rows: text that cannot collide ─────────────────────────── */
/* `-webkit-line-clamp` only works while the element keeps
   `display:-webkit-box`; the moment anything else sets `display`, the clamp is
   silently ignored, the title runs to three lines and lands on top of
   "Tap to watch" — which is what Caleb photographed. Reinforced here, and the
   text column is an explicit flex column so the two lines can never overlap
   however long a YouTube title runs. */
body.pm-tier-child .pmch-item{ align-items: start !important; }
body.pm-tier-child .pmch-item > div:last-child{
  display: flex !important; flex-direction: column !important;
  gap: 3px !important; min-width: 0 !important; justify-content: center !important;
  min-height: 56px !important;                 /* match the thumbnail, so short rows still centre */
}
body.pm-tier-child .pmch-item__title{
  display: -webkit-box !important;
  -webkit-box-orient: vertical !important;
  -webkit-line-clamp: 2 !important;
  overflow: hidden !important;
  font: 600 13.5px/1.35 var(--kp-font) !important;
  letter-spacing: -0.01em !important;
  margin: 0 !important;
}
body.pm-tier-child .pmch-item__sub{
  margin: 0 !important;
  font: 450 11.5px/1.25 var(--kp-font) !important;
  white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
}

/* The active row was a fixed purple gradient with fixed-purple shadow. On teal
   that is the "darker code colour in the back" — it is literally the old purple
   showing through. Themed, and the text colours follow it. */
body.pm-tier-child .pmch-item.is-active{
  background: var(--kt-primary-grad) !important;
  border-color: color-mix(in srgb, #FFFFFF 24%, transparent) !important;
  box-shadow: 0 10px 24px -14px color-mix(in srgb, var(--kt-chrome-deep) 70%, transparent) !important;
}
body.pm-tier-child .pmch-item.is-active .pmch-item__title{ color:#FFFFFF !important; }
body.pm-tier-child .pmch-item.is-active .pmch-item__sub{ color: rgba(255,255,255,.88) !important; }
body.pm-tier-child .pmch-item:not(.is-active) .pmch-item__sub{ color: var(--kp-ink-mute) !important; }
body.pm-tier-child .pmch-item:not(.is-active) .pmch-item__title{ color: var(--kp-ink) !important; }

/* the count chip beside "My playlist" carried a fixed violet shadow too */
body.pm-tier-child .pmch-playlist__count{
  box-shadow: 0 3px 10px -4px color-mix(in srgb, var(--kt-chrome-deep) 65%, transparent) !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   13) STRIP IT (2026-09-15) — Caleb: "remove the boarder or whateve shadow is
       on those ... remove anytign there in the abck ... i dotn wnana keep oing
       this".

   Fair. Three rounds of re-tinting was the wrong approach. Everything behind
   these surfaces is removed outright: borders, shadows, filters, and the
   decorative pseudo-layers. Nothing is left that can show through an edge.

   Two real culprits found in the final audit and killed here:
     • a SECOND, later rule re-declaring the old purple gradient
       (#7C3AED → #A855F7 → #D946EF) on .pmch-grid::before/::after, which is why
       re-tinting upstream never stuck;
     • .pmch-item__thumb::after — a black overlay (rgba(0,0,0,.4)) painted down
       the bottom of EVERY playlist thumbnail, which darkened the covers.
   ══════════════════════════════════════════════════════════════════════════ */

/* the strips: theme colour, nothing behind them */
body.pm-tier-child .pmch-grid::before,
body.pm-tier-child .pmch-grid::after{
  background: var(--kt-banner-grad) !important;
  background-image: var(--kt-banner-grad) !important;
  border: 0 !important;
  box-shadow: none !important;
  filter: none !important;
}

/* every surface in that block: no edge, no shadow, no filter */
body.pm-tier-child .pmch-shell,
body.pm-tier-child .pmch-topbar,
body.pm-tier-child .pmch-icons,
body.pm-tier-child .pmch-crewbar,
body.pm-tier-child .pmch-crew__scene,
body.pm-tier-child .pmch-quicklearn,
body.pm-tier-child .pmch-video-card,
body.pm-tier-child .pmch-video-wrap,
body.pm-tier-child .pmch-playlist,
body.pm-tier-child .pmch-item,
body.pm-tier-child .pmch-item:hover,
body.pm-tier-child .pmch-item.is-active,
body.pm-tier-child .pmch-playlist__list > .pmch-item.is-active{
  border: 0 !important;
  box-shadow: none !important;
  filter: none !important;
}

/* the decorative sheen/overlay layers that sat on top of them */
body.pm-tier-child .pmch-video-card::after,
body.pm-tier-child .pmch-playlist::after,
body.pm-tier-child .pmch-homework::after,
body.pm-tier-child .pmch-crewbar__shimmer,
body.pm-tier-child .pmch-crewbar__shimmer::before,
body.pm-tier-child .pmch-item__thumb::after{
  content: none !important;
  display: none !important;
  background: none !important;
}

/* the white cards keep ONE hairline so they still read as cards — nothing that
   can cast or stack. */
body.pm-tier-child .pmch-video-card,
body.pm-tier-child .pmch-playlist,
body.pm-tier-child .pmch-sessions,
body.pm-tier-child .pmch-homework,
body.pm-tier-child .ktd-card{
  border: 1px solid rgba(17,24,39,.07) !important;
  box-shadow: none !important;
}
body.pm-tier-child .pmch-video-card:hover,
body.pm-tier-child .pmch-playlist:hover,
body.pm-tier-child .pmch-sessions:hover,
body.pm-tier-child .pmch-homework:hover,
body.pm-tier-child .ktd-card:hover{ box-shadow: none !important; }

/* the covers, undarkened */
body.pm-tier-child .pmch-item__thumb{ box-shadow: none !important; }

/* ══════════════════════════════════════════════════════════════════════════
   14) HEADER ORDER (2026-09-15) — Caleb: "move the notivaitons to the left, on
       the right side of the search bar. move the colour and translation icon
       nd install the app close to the name but spaced out nicely not crunched
       together in the header".

   Three of these controls are injected by JavaScript at different moments —
   the bell by the notifications module, the flag by js/pm-i18n.js (which
   inserts itself `before:[data-pm-install]`), the palette by
   js/kid-theme-switcher.js (`topbar.insertBefore(host, userPod)`). Their DOM
   order therefore depends on which script finishes first, which is not
   something to rely on.

   So the ORDER IS DECLARED HERE, not in the DOM. `.nx-topbar` is already a
   flexbox, so flex `order` fixes the arrangement no matter how the children
   arrive, and nothing in those three scripts has to change.

        [ search ] [ bell ] ←——— gap ———→ [ flag ] [ palette ] [ Install ] [ Ryan ]
   ══════════════════════════════════════════════════════════════════════════ */
body.pm-tier-child .nx-topbar{
  /* flex-END, not flex-start. Both give the same result while the search is
     mounted (its auto margin below eats the slack and pushes everything after
     it to the right edge) — but they differ the moment the search is NOT
     there, which happens on small screens and in embeds. flex-start would let
     the whole group slide back to the left; flex-end keeps it pinned right no
     matter which header controls are present. The header must not re-flow
     because a JS-mounted control came or went. */
  justify-content: flex-end !important;
  gap: 12px !important;
}
/* 2026-09-15 — THE spacer. Exactly one auto margin in this header, and it
   hangs off .nx-search, which is the only right-hand-group neighbour that is
   in the page's own markup (everything after it — the bell, the flag, the
   palette — is injected or relocated by JS and can be absent at any moment).
   One auto margin here eats all the free space, so every control after it
   sits flush against the right edge of the bar and cannot drift inward. */
body.pm-tier-child .nx-topbar .nx-search                {
  order: 1 !important;
  /* Fallback only. The bell is relocated into this bar by JS, so for the first
     moments after load it is not here yet; during that window the search holds
     the gap open so nothing is sitting in the wrong place while the page
     settles. The line below hands the gap over the instant the bell arrives. */
  margin-right: auto !important;
}
/* ":has(~ ...)" reads DOM ORDER, and relocateStripToTopbar() inserts the strip
   after the search and before .nx-userpod — so this matches as soon as the bell
   is in, no matter what flex `order` the two end up painted in. Exactly one
   auto margin exists at any instant: it is on the search before the handoff and
   on the bell after it, never on both. */
body.pm-tier-child .nx-topbar .nx-search:has(~ .nx-notif-strip--topbar){
  margin-right: 0 !important;
}

/* the bell sits immediately right of the search, and its auto margin is what
   pushes every later item over to the name */
/* 2026-09-15 — the auto-margin USED to live here, and that was a mistake: the
   notification strip is relocated into the header by JS and is not always
   present (it disappears while the search is open), so the entire right-hand
   group collapsed leftwards the moment the search was clicked — which is
   exactly the jump Caleb photographed. The spacer now hangs off .pmlang below,
   which is stable, and the header reserves the strip's width so nothing shifts
   even when it is absent. */
body.pm-tier-child .nx-topbar .nx-notif-strip--topbar   {
  order: 2 !important;
  /* the bell sits SNUG beside the search, and the gap opens AFTER it — Caleb:
     "i asked for it to be next to the search bar on the right side of it" */
  margin: 0 auto 0 0 !important;
}

/* No auto margins down here. An earlier attempt put one on .pmlang and a
   second on .kt-hdr with a "~" sibling guard to cancel the duplicate — but "~"
   matches DOM order while these items are arranged by flex `order`, so the
   guard never matched, and in any case the `margin: 0 !important` rule below
   (written later, same specificity) silently killed both. The result was the
   whole group packing left with dead space on the right. Fixed above. */
body.pm-tier-child .nx-topbar .pmlang                   { order: 3 !important; }
body.pm-tier-child .nx-topbar .kt-hdr                   { order: 4 !important; }
body.pm-tier-child .nx-topbar [data-pm-install]         { order: 5 !important; }
body.pm-tier-child .nx-topbar .dash-theme-toggle        { order: 6 !important; }
body.pm-tier-child .nx-topbar .nx-userpod               {
  order: 7 !important;
  margin-left: 4px !important;              /* a touch more air before the name */
}

/* "spaced out nicely, not crunched": the three icon controls get equal, roomy
   hit areas so they read as a set rather than a huddle. */
body.pm-tier-child .nx-topbar .pmlang,
body.pm-tier-child .nx-topbar .kt-hdr{ margin: 0 !important; }
body.pm-tier-child .nx-topbar [data-pm-install]{
  margin: 0 !important;
  padding: 9px 15px !important;
  white-space: nowrap !important;
}

/* On a narrow window the header would otherwise crush: let the search give way
   first, and keep every control at full size. */
@media (max-width: 1100px){
  body.pm-tier-child .nx-topbar .nx-search{ max-width: 320px !important; }
}
@media (max-width: 900px){
  body.pm-tier-child .nx-topbar{ gap: 8px !important; }
  body.pm-tier-child .nx-topbar .nx-search{ max-width: 200px !important; }
}


/* The header keeps its height whether or not the bell is mounted, so opening
   the search cannot make the whole bar jump. */
body.pm-tier-child .nx-topbar{ min-height: 68px !important; }

/* ══════════════════════════════════════════════════════════════════════════
   15 · "YOU'RE ALL CAUGHT UP" — the bell's resting state
   ──────────────────────────────────────────────────────────────────────────
   2026-09-15. The header bell used to delete itself whenever the count hit
   zero, so a few seconds after every reload it simply vanished and the header
   re-flowed. Zero is now the normal state for a child (their inbox only
   carries schooling events), so the bell stays put and the panel explains the
   quiet instead of showing an empty white box.
   ══════════════════════════════════════════════════════════════════════════ */
body.pm-tier-child .nx-notif-zero{
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 30px 24px 26px;
  background: var(--kp-inset);
  border-radius: var(--kp-r-sm);
  font-family: var(--kp-font);
}
body.pm-tier-child .nx-notif-zero svg{
  width: 30px;
  height: 30px;
  color: var(--kt-accent-bright, #2FA6A0);
  opacity: .75;
}
body.pm-tier-child .nx-notif-zero__title{
  margin: 0;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--kp-ink);
}
body.pm-tier-child .nx-notif-zero__sub{
  margin: 0;
  max-width: 30ch;
  font-size: 12.5px;
  font-weight: 400;          /* fine print, per Caleb — never bold */
  line-height: 1.5;
  color: var(--kp-ink-mute);
}

/* The bell reads as "quiet", not "broken", when nothing is waiting: no red
   wash, no badge, just the outline sitting with the other header controls. */
body.pm-tier-child .nx-topbar .nx-notif-strip--topbar .nx-notif-trigger__badge[style*="none"]{
  display: none !important;
}
