/* ============================================================
   periodic.css — the table itself, plus the two things that are always
   drawn next to it: an element card and an electron configuration.

   Cell size is one custom property, --pt-cell, set in pixels by
   ptable.js from the panel's measured width. Everything inside a cell —
   the symbol, the atomic number, the value line, the border radius — is
   sized as a fraction of it, so the same table works at 18 px a cell in
   a sidebar preview and at 52 px a cell on a wide monitor without a
   single media query.
   ============================================================ */

/* Written mobile first. The base rules are the phone case — a table
   wider than the screen, scrolled sideways, with a big magnification on
   tap because the names have to be small to fit. The media query at the
   bottom only relaxes the magnification once there is room to read
   without it. */

.pt {
  --pt-cell: 46px;
  --pt-gap: 2px;
  /* How much a chosen cell grows. Large on a phone, where the name is at
     its smallest and a finger is covering half the cell. */
  --pt-mag: 2.2;
  width: 100%;
  /* Not clipped: a magnified cell in the top row has to be allowed to
     grow past the edge of the table's own box. */
  overflow: visible;
  /* Positioned so a cell's offsetLeft is measured against the scroll
     content, which is what keepInView() does its arithmetic in. */
  position: relative;
}

.pt.is-scrolling {
  overflow-x: auto;
  /* overflow-x:auto forces overflow-y to compute as auto too, so the
     vertical room for a magnified cell has to come from padding rather
     than from letting it overflow. */
  padding: 22px 0 26px;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.pt__hint {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-2);
  padding: 7px 12px;
  border-radius: var(--r-pill);
  border: 1px dashed var(--line-strong);
  background: var(--surface);
  font-size: var(--t-xs);
  color: var(--ink-3);
  text-align: center;
  justify-content: center;
}

/* Cells are TALLER than they are wide. A square cell fits an atomic
   number and a symbol; this lesson is somebody's first meeting with the
   table, so every cell also carries the element's name, and that needs a
   line of its own. --pt-row is the height that follows from the width. */
.pt {
  --pt-row: calc(var(--pt-cell) * 1.32);
}

.pt__grid {
  display: grid;
  position: relative; /* containing block for the scrim */
  grid-template-columns: repeat(19, var(--pt-cell));
  grid-template-rows:
    calc(var(--pt-cell) * 0.62)
    repeat(7, var(--pt-row))
    calc(var(--pt-cell) * 0.6)
    repeat(2, var(--pt-row));
  gap: var(--pt-gap);
  align-content: start;

  /* The BOX has to be as wide as the tracks, not as wide as the panel.

     A block-level grid takes its container's width and lets fixed tracks
     overflow it, which has two consequences on a narrow screen: the
     scrim is sized to that box and so stops dimming halfway across the
     table, and centring an overflowing box puts the leading columns at a
     negative offset nothing can scroll back to. Sizing to max-content
     fixes both — and `margin-inline: auto` still centres it when there
     IS room, because auto margins collapse to zero once the free space
     goes negative. */
  width: max-content;
  margin-inline: auto;
}

/* Belt and braces: once the table is wider than its panel it starts hard
   at the left edge, whatever a future edit does to the margins above. */
.pt.is-scrolling .pt__grid {
  margin-inline: 0;
}

.pt[data-mode="wide"] .pt__grid {
  grid-template-columns: repeat(33, var(--pt-cell));
  grid-template-rows: calc(var(--pt-cell) * 0.62) repeat(7, var(--pt-row));
}

/* ---------------- headers ---------------- */

.pt__hdr {
  display: grid;
  place-items: center;
  font-size: calc(var(--pt-cell) * 0.26);
  font-weight: 700;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  user-select: none;
}

/* ---------------- one cell ---------------- */

.pt__cell {
  --cell-c: var(--ink-3);
  --ox: center;
  --oy: center;
  position: relative;
  cursor: pointer;
  transform-origin: var(--ox) var(--oy);
  touch-action: manipulation;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 1px;
  overflow: hidden;
  line-height: 1.02;
  border-radius: calc(var(--pt-cell) * 0.13);
  border: 1px solid color-mix(in srgb, var(--cell-c) 42%, transparent);
  background: color-mix(in srgb, var(--cell-c) 15%, transparent);
  color: var(--ink);
  font: inherit;
  text-align: center;
  transition: transform 120ms var(--ease), box-shadow var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}

.pt__cell:disabled {
  cursor: not-allowed;
}

/* ---------------- magnify the chosen cell ----------------

   The element names have to be small to fit eighteen columns on a
   screen, so choosing a cell blows it up — symbol, name and all — until
   it is comfortably readable and comfortably tappable. A plain scale is
   used rather than swapping in bigger text, because scaling takes the
   whole cell with it and needs no second layout.

   At 2.2x a 7px name becomes 15px and a 46px cell becomes 101px, which
   is well clear of a fingertip.                                        */

/* The scrim. Sits above the ordinary cells and below the enlarged one,
   so the table it came from stays legible as context without competing
   with the thing being read. */
.pt__scrim {
  position: absolute;
  /* Exactly the grid's box. A negative inset would extend the scrollable
     area of the table on its right-hand side. */
  inset: 0;
  z-index: 8;
  pointer-events: none;
  opacity: 0;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  transition: opacity 180ms var(--ease);
}

.pt.has-peek .pt__scrim,
.pt.has-focus .pt__scrim {
  opacity: 1;
}

/* Cells a panel had already faded out — the elements outside the chosen
   family in §11, the ones not yet built in §04 — would be dimmed twice
   and disappear completely, taking the shape of the table with them.
   The table is still the context for the thing being read, so they are
   brought back up to meet the scrim rather than through it. */
.pt.has-peek .pt__cell.is-dim,
.pt.has-focus .pt__cell.is-dim {
  opacity: 0.42;
}

.pt__cell.is-peek,
.pt__cell:focus-visible {
  transform: scale(var(--pt-mag));
  z-index: 12;
  border-color: var(--cell-c);
  border-width: 1px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.6), 0 0 0 1px color-mix(in srgb, var(--ink) 22%, transparent);
}

/* An enlarged cell has to be OPAQUE.

   A cell's family tint is a colour mixed with `transparent`, which is
   fine at full size — the page shows through and the whole table reads
   as one surface. Blown up over its neighbours it is a different story:
   the cells underneath show straight through the enlarged one and its
   symbol, number and name end up sitting on top of somebody else's
   colours. So the tint is re-mixed against a solid surface instead of
   against nothing.

   Heat-map cells set an opaque colour inline and that shorthand beats
   this, which is correct: they are already opaque. */
.pt__cell.is-peek,
.pt__cell:focus-visible {
  background-color: var(--surface-solid);
  background-image: linear-gradient(
    color-mix(in srgb, var(--cell-c) 24%, transparent),
    color-mix(in srgb, var(--cell-c) 24%, transparent)
  );
}

/* Anything the panel has deliberately marked stays above the scrim —
   otherwise picking two elements to compare in §09 would fade the first
   one out the moment the second was chosen, and the marked answers on a
   trainer question would disappear behind their own feedback. */
.pt__cell.is-selected,
.pt__cell.is-right,
.pt__cell.is-wrong,
.pt__cell.is-target {
  z-index: 9;
}

/* Hover magnification only where there is a real pointer. On a
   touchscreen :hover sticks after a tap, which would leave a cell
   enlarged with no way to put it back. */
@media (hover: hover) and (pointer: fine) {
  .pt__cell:hover:not(:disabled) {
    transform: scale(calc(var(--pt-mag) * 0.82));
    z-index: 10;
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
    /* Opaque on hover as well, for the same reason as on tap — but
       WITHOUT the scrim. Dimming the whole table every time the mouse
       crosses a cell would strobe. */
    background-color: var(--surface-solid);
    background-image: linear-gradient(
      color-mix(in srgb, var(--cell-c) 24%, transparent),
      color-mix(in srgb, var(--cell-c) 24%, transparent)
    );
  }

  .pt__cell.is-peek:hover:not(:disabled) {
    transform: scale(var(--pt-mag));
  }
}

/* Grow away from the edge, not through it. Grid columns are 1-based and
   column 1 is the period label, so an element in group 1 sits at
   data-col 2 and one in group 18 at data-col 19. */
.pt__cell[data-col="2"],
.pt__cell[data-col="3"] { --ox: left; }

.pt[data-mode="standard"] .pt__cell[data-col="18"],
.pt[data-mode="standard"] .pt__cell[data-col="19"] { --ox: right; }

.pt[data-mode="wide"] .pt__cell[data-col="32"],
.pt[data-mode="wide"] .pt__cell[data-col="33"] { --ox: right; }

/* Row 1 is the group-number header, so period 1 is row 2. Row 8 is
   period 7 and row 11 is the second f-block strip. */
.pt__cell[data-row="2"] { --oy: top; }
.pt__cell[data-row="8"],
.pt__cell[data-row="11"] { --oy: bottom; }

.pt__z {
  font-size: calc(var(--pt-cell) * 0.22);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.pt__sym {
  font-size: calc(var(--pt-cell) * 0.34);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* The element name, fitted to the cell.

   Every cell is the same width and no two names are, so a single font
   size either wastes the room "Tin" leaves or clips "Rutherfordium".
   ptable.js writes the character count into --nlen and this divides by
   it: about 0.55em per character, so a name of n characters wants a font
   of roughly (0.9 x cell) / (0.55 x n). Capped so short names do not
   balloon, floored so long ones stay legible, and any residue is hidden
   rather than allowed to push the symbol around. */
.pt__name {
  font-size: max(5.5px, min(
    calc(var(--pt-cell) * 0.168),
    calc(var(--pt-cell) * 1.62 / var(--nlen, 8))
  ));
  line-height: 1.15;
  color: var(--ink-2);
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  letter-spacing: -0.01em;
}

.pt__sub {
  font-size: calc(var(--pt-cell) * 0.19);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
}

/* Compact drops the value line; mini drops the atomic number too. The
   NAME survives both, because it is the reason the cell exists. */
.pt--compact .pt__sub,
.pt--mini .pt__z,
.pt--mini .pt__sub {
  display: none;
}

/* ---------------- states ---------------- */

.pt__cell.is-dim {
  opacity: 0.16;
}

.pt__cell.is-on {
  border-color: var(--cell-c);
  background: color-mix(in srgb, var(--cell-c) 38%, transparent);
}

/* Marked states sit ABOVE the dimming scrim (z 8) and below an enlarged
   cell (z 12). Otherwise picking a second element to compare in §09
   would fade the first one out, and a trainer question's marked answers
   would vanish behind their own feedback. */
.pt__cell.is-selected {
  outline: 2px solid var(--ink);
  outline-offset: -1px;
  z-index: 9;
}

.pt__cell.is-target {
  outline: 2px dashed var(--accent);
  outline-offset: -1px;
}

.pt__cell.is-right {
  outline: 2px solid var(--ok);
  outline-offset: -1px;
  z-index: 9;
}

.pt__cell.is-wrong {
  outline: 2px solid var(--bad);
  outline-offset: -1px;
  z-index: 9;
}

/* A painted cell — a heat map — sets its own background inline, so the
   family tint underneath has to be switched off or the two would mix. */
.pt__cell.is-paint {
  border-color: rgba(0, 0, 0, 0.18);
}

/* The cell picks black or white text to suit whatever colour it was
   painted, and the atomic number and value line have to follow it. Left
   at their own muted colour they end up dark grey on a warm red — the
   one part of the heat map you cannot read is the part telling you which
   element you are looking at. */
.pt__cell.is-paint .pt__z,
.pt__cell.is-paint .pt__name,
.pt__cell.is-paint .pt__sub {
  color: inherit;
  opacity: 0.78;
}

.pt__gapnote {
  display: grid;
  place-items: center;
  font-size: calc(var(--pt-cell) * 0.24);
  color: var(--ink-3);
  font-style: italic;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
}

/* ---------------- more room than a phone has ----------------
   The only thing that changes on a wider screen is that the cells are
   already big enough to read, so the magnification can be gentler. */
@media (min-width: 900px) {
  .pt {
    --pt-mag: 1.8;
  }
}

/* ---------------- colour by family (the default) ---------------- */

.pt__cell[data-cat="alkali"] { --cell-c: var(--cat-alkali); }
.pt__cell[data-cat="alkaline"] { --cell-c: var(--cat-alkaline); }
.pt__cell[data-cat="transition"] { --cell-c: var(--cat-transition); }
.pt__cell[data-cat="post"] { --cell-c: var(--cat-post); }
.pt__cell[data-cat="metalloid"] { --cell-c: var(--cat-metalloid); }
.pt__cell[data-cat="nonmetal"] { --cell-c: var(--cat-nonmetal); }
.pt__cell[data-cat="halogen"] { --cell-c: var(--cat-halogen); }
.pt__cell[data-cat="noble"] { --cell-c: var(--cat-noble); }
.pt__cell[data-cat="lanthanide"] { --cell-c: var(--cat-lanthanide); }
.pt__cell[data-cat="actinide"] { --cell-c: var(--cat-actinide); }

/* ---------------- colour by block ---------------- */

.pt[data-color="block"] .pt__cell[data-blk="s"] { --cell-c: var(--blk-s); }
.pt[data-color="block"] .pt__cell[data-blk="p"] { --cell-c: var(--blk-p); }
.pt[data-color="block"] .pt__cell[data-blk="d"] { --cell-c: var(--blk-d); }
.pt[data-color="block"] .pt__cell[data-blk="f"] { --cell-c: var(--blk-f); }

/* ---------------- colour by nothing ---------------- */

.pt[data-color="plain"] .pt__cell {
  --cell-c: var(--ink-3);
}

/* ---------------- the legend ---------------- */

.legend--pt {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-3);
}

.legend--pt .legend__item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--t-xs);
  color: var(--ink-2);
}

.legend--pt .legend__item b {
  color: var(--ink-3);
  font-weight: 600;
}

.legend__dot {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  flex: none;
  background: var(--ink-3);
}

.legend__dot[data-cat="alkali"] { background: var(--cat-alkali); }
.legend__dot[data-cat="alkaline"] { background: var(--cat-alkaline); }
.legend__dot[data-cat="transition"] { background: var(--cat-transition); }
.legend__dot[data-cat="post"] { background: var(--cat-post); }
.legend__dot[data-cat="metalloid"] { background: var(--cat-metalloid); }
.legend__dot[data-cat="nonmetal"] { background: var(--cat-nonmetal); }
.legend__dot[data-cat="halogen"] { background: var(--cat-halogen); }
.legend__dot[data-cat="noble"] { background: var(--cat-noble); }
.legend__dot[data-cat="lanthanide"] { background: var(--cat-lanthanide); }
.legend__dot[data-cat="actinide"] { background: var(--cat-actinide); }

.legend__dot[data-blk="s"] { background: var(--blk-s); }
.legend__dot[data-blk="p"] { background: var(--blk-p); }
.legend__dot[data-blk="d"] { background: var(--blk-d); }
.legend__dot[data-blk="f"] { background: var(--blk-f); }

/* A continuous scale needs a bar, not dots. */
.rampbar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-3);
  font-size: var(--t-xs);
  color: var(--ink-3);
}

.rampbar__track {
  height: 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: linear-gradient(90deg, var(--ramp-lo), var(--ramp-mid), var(--ramp-hi));
}

/* ============================================================
   The element card — one element, everything derived
   ============================================================ */

.elcard {
  display: grid;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface);
  border-left: 4px solid var(--elc, var(--accent));
}

.elcard__top {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
}

.elcard__sym {
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  flex: none;
  border-radius: var(--r-md);
  border: 1px solid color-mix(in srgb, var(--elc, var(--accent)) 45%, transparent);
  background: color-mix(in srgb, var(--elc, var(--accent)) 16%, transparent);
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
}

.elcard__sym small {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
  margin-top: 3px;
}

.elcard__name {
  min-width: 0;
}

.elcard__name h3 {
  margin: 0 0 2px;
}

.elcard__name p {
  margin: 0;
  font-size: var(--t-sm);
  color: var(--ink-3);
}

.elcard__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: var(--s-2);
}

.elfact {
  padding: 8px 12px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--line);
}

.elfact span {
  display: block;
  font-size: var(--t-xs);
  color: var(--ink-3);
  letter-spacing: 0.04em;
}

.elfact b {
  font-size: var(--t-sm);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.elfact.is-derived {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* ============================================================
   Electron configuration display
   ============================================================ */

.cfg {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: var(--t-md);
  line-height: 1.3;
}

.cfg--sm {
  font-size: var(--t-sm);
  gap: 4px;
}

.cfg--lg {
  font-size: var(--t-lg);
}

.cfg__core {
  padding: 2px 9px;
  border-radius: var(--r-sm);
  border: 1px dashed var(--line-strong);
  color: var(--ink-3);
}

.cfg__sub {
  --sc: var(--ink-3);
  padding: 2px 7px;
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--sc) 40%, transparent);
  background: color-mix(in srgb, var(--sc) 14%, transparent);
  color: var(--ink);
  white-space: nowrap;
  transition: all var(--dur) var(--ease);
}

.cfg__sub[data-l="s"] { --sc: var(--blk-s); }
.cfg__sub[data-l="p"] { --sc: var(--blk-p); }
.cfg__sub[data-l="d"] { --sc: var(--blk-d); }
.cfg__sub[data-l="f"] { --sc: var(--blk-f); }

.cfg__sub.is-new {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

.cfg__sub.is-ghost {
  opacity: 0.28;
}

.cfg__sub.is-moved {
  border-style: dashed;
  border-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 16%, transparent);
}

/* The plain-text version, for copying onto exam paper. */
.cfg-plain {
  font-family: var(--mono);
  font-size: var(--t-sm);
  color: var(--ink-2);
  word-break: break-word;
}

/* ============================================================
   Orbital boxes — Pauli and Hund made visible
   ============================================================ */

.orbs {
  display: grid;
  gap: var(--s-3);
}

.orbrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}

.orbrow__label {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 700;
  min-width: 34px;
  color: var(--ink);
}

.orbrow__boxes {
  display: flex;
  gap: 3px;
}

.orbbox {
  --ob: var(--ink-3);
  width: 30px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--ob) 55%, transparent);
  background: color-mix(in srgb, var(--ob) 10%, transparent);
  font-size: 15px;
  line-height: 1;
  letter-spacing: -2px;
  color: var(--ink);
  font-family: var(--mono);
}

.orbbox[data-l="s"] { --ob: var(--blk-s); }
.orbbox[data-l="p"] { --ob: var(--blk-p); }
.orbbox[data-l="d"] { --ob: var(--blk-d); }
.orbbox[data-l="f"] { --ob: var(--blk-f); }

.orbbox.is-full {
  background: color-mix(in srgb, var(--ob) 26%, transparent);
}

.orbbox.is-single {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ob) 45%, transparent);
}

.orbrow__note {
  font-size: var(--t-xs);
  color: var(--ink-3);
}

/* ============================================================
   Shell diagram — the Bohr picture, 2 8 8 2
   ============================================================ */

.shells {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}

.shellpip {
  display: grid;
  gap: 2px;
  justify-items: center;
  padding: 7px 11px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--surface-2);
  min-width: 46px;
}

.shellpip b {
  font-size: var(--t-md);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.shellpip span {
  font-size: var(--t-xs);
  color: var(--ink-3);
}

.shellpip.is-valence {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
