/* ============================================================
   GOALS · the viewer
   ------------------------------------------------------------
   A grid of 108 clips with live filtering, hover-to-play and a
   modal. Tier 3 tokens throughout; nothing here invents a colour,
   a size or a gap.

   THE CARD IS A FRAME, NOT A BOX. No shadow, no fill, no radius —
   the system draws with hairlines (D6/D9), so a card is a picture
   with a rule under it and the rule is the only thing that moves
   on hover. What arrives on hover is the footage itself, which is
   the one thing a still cannot say.
   ============================================================ */

/* A hidden element must stay hidden even when a rule here gives it a
   display — .g-field is flex, and [hidden] loses to a class selector. */
[hidden] { display: none !important; }

/* ---------- the control bar -------------------------------- */

/* Sticky under the nav, so the filters stay reachable through a
   108-card scroll. Its own hairline is the only edge it has. */
.g-controls {
  position: sticky;
  top: var(--kdb-nav-height);
  z-index: 3;
  background: var(--kdb-page-ground);
  border-block-end: var(--kdb-rule-divide) solid var(--kdb-rule-divide-ink);
  padding-block: var(--kdb-space-snug);
  margin-block-end: var(--kdb-space-block);
}
.g-controls__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kdb-space-snug);
  align-items: flex-end;
}

.g-field { display: flex; flex-direction: column; gap: var(--kdb-space-hair); }
.g-field > label {
  font-family: var(--kdb-family-archivo);
  font-size: var(--kdb-size-label);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-muted);
}

/* A select, drawn the way the system draws: a rule under it, no
   box. The chevron is inline SVG rather than the UA arrow, which
   arrives in the UA's own blue-grey and cannot be tokenised. */
.g-select {
  appearance: none;
  font: inherit;
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-text), "wght" var(--kdb-wght-medium);
  font-size: var(--kdb-size-small);
  color: var(--kdb-text-primary);
  background: transparent;
  border: 0;
  border-block-end: var(--kdb-rule-strong) solid var(--kdb-rule-strong-ink);
  border-radius: 0;
  padding: var(--kdb-space-hair) var(--kdb-space-base) var(--kdb-space-hair) 0;
  min-width: 11ch;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'><path d='M1 1l4 4 4-4' fill='none' stroke='%2314181d' stroke-width='1.2'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--kdb-space-hair) center;
  transition: border-color var(--kdb-motion-tick) var(--kdb-motion-curve);
}
.g-select:hover { border-block-end-color: var(--kdb-accent-mark); }
.g-select:focus-visible { outline: 2px solid var(--kdb-accent-mark); outline-offset: 3px; }

/* Tag chips. The system's .k-tag is type in a container; these are
   the toggling version of it. */
.g-chips { display: flex; flex-wrap: wrap; gap: var(--kdb-space-tight); }
.g-chip {
  font-family: var(--kdb-family-archivo);
  font-size: var(--kdb-tag-size);
  letter-spacing: var(--kdb-tag-track);
  text-transform: uppercase;
  color: var(--kdb-text-secondary);
  background: transparent;
  border: var(--kdb-rule-divide) solid var(--kdb-border-hairline);
  padding: var(--kdb-tag-pad-y) var(--kdb-tag-pad-x);
  cursor: pointer;
  transition: color var(--kdb-motion-tick) var(--kdb-motion-curve),
              border-color var(--kdb-motion-tick) var(--kdb-motion-curve);
}
.g-chip:hover { border-color: var(--kdb-accent-mark); color: var(--kdb-text-primary); }
.g-chip[aria-pressed="true"] {
  color: var(--kdb-text-inverse);
  background: var(--kdb-border-strong);
  border-color: var(--kdb-border-strong);
}

.g-reset {
  font-family: var(--kdb-family-archivo);
  font-size: var(--kdb-size-label);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-muted);
  background: none; border: 0; padding: 0; cursor: pointer;
  border-block-end: var(--kdb-rule-hair) solid var(--kdb-rule-hair-ink);
}
.g-reset:hover { color: var(--kdb-text-primary); border-block-end-color: currentColor; }

/* ---------- the count -------------------------------------- */

/* The number is the headline, so it takes the figure ramp and the
   condensed width the width law reserves for numerals at scale. */
.g-count { display: flex; align-items: baseline; gap: var(--kdb-space-snug); }
.g-count__n {
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-figure), "wght" var(--kdb-wght-heavy);
  font-size: var(--kdb-size-figure);
  line-height: var(--kdb-leading-figure);
  font-variant-numeric: tabular-nums;
  color: var(--kdb-text-primary);
}
.g-count__label { color: var(--kdb-text-muted); }

/* ---------- the grid --------------------------------------- */

/* The column count is set by JS so the set fits the window: a filter that
   leaves three cards gets three big ones, 119 gets small ones and scrolls.
   --cols falls back to auto-fill for the first paint and for no-JS. */
.g-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, auto-fill), minmax(0, 1fr));
  gap: var(--kdb-space-base);
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;          /* the FLIP ghosts are laid over it */
}
.g-grid:not([style*="--cols"]) {
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* A card that has been filtered out is gone from the DOM before it can be
   animated, so a still of it is laid over where it was and faded. */
.g-ghosts {
  position: absolute;
  inset: 0;
  pointer-events: none;
  grid-column: 1 / -1;
  grid-row: 1;
}
.g-ghost {
  position: absolute;
  background: var(--kdb-neutral-20) center/cover no-repeat;
  transform-origin: 50% 50%;
}

.g-card {
  margin: 0;
  /* Arrival is staggered by index — D21's series timing, set as a
     custom property from JS so the CSS owns the curve. */
  animation: g-arrive var(--kdb-motion-draw) var(--kdb-motion-curve) both;
  animation-delay: calc(var(--i, 0) * var(--kdb-motion-stagger));
}
@keyframes g-arrive {
  from { opacity: 0; transform: translateY(var(--kdb-space-tight)); }
  to   { opacity: 1; transform: none; }
}

.g-card__btn {
  display: block;
  width: 100%;
  padding: 0;
  background: none;
  border: 0;
  text-align: start;
  cursor: pointer;
  color: inherit;
  font: inherit;
}

.g-card__frame {
  display: block;            /* it is a <span> inside a button — without this the
                                aspect-ratio box and its absolute children collapse */
  position: relative;
  overflow: hidden;
  /* A clip is 16:9; a shirt is not. The page sets the shape once. */
  aspect-ratio: var(--frame-aspect, 16 / 9);
  background: var(--kdb-surface-sunken);
  border-block-end: var(--kdb-rule-divide) solid var(--kdb-rule-divide-ink);
}
.g-card__frame img,
.g-card__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The clip sits on top of the still and is revealed, not swapped —
   a swap flashes the background through between two decodes. */
.g-card__frame video { opacity: 0; transition: opacity var(--kdb-motion-draw) var(--kdb-motion-curve); }
.g-card.is-playing .g-card__frame video { opacity: 1; }

/* The rule under the frame is the hover state. It draws in from the
   left at the accent's mark tier — the one accent allowed to carry
   meaning — which is the whole of the interaction's colour. */
.g-card__frame::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 2px;
  background: var(--kdb-accent-mark);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--kdb-motion-draw) var(--kdb-motion-curve);
}
.g-card__btn:hover .g-card__frame::after,
.g-card__btn:focus-visible .g-card__frame::after { transform: scaleX(1); }
.g-card__btn:focus-visible { outline: 2px solid var(--kdb-accent-mark); outline-offset: 4px; }

/* The goal's number, in the annotation margin's voice — it is a
   count, which is exactly what that tier is for. */
.g-card__n {
  position: absolute;
  inset-block-start: var(--kdb-space-tight);
  inset-inline-start: var(--kdb-space-tight);
  z-index: 1;
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-figure), "wght" var(--kdb-wght-heavy);
  font-size: var(--kdb-size-caption);
  font-variant-numeric: tabular-nums;
  color: var(--kdb-text-inverse);
  mix-blend-mode: difference;
}

.g-card__body {
  display: flex;
  margin-block-start: var(--kdb-card-label-gap);
  align-items: baseline;
  gap: var(--kdb-space-tight);
}
.g-card__opp {
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-text), "wght" var(--kdb-wght-medium);
  font-size: var(--kdb-size-body);
  letter-spacing: var(--kdb-track-body);
  color: var(--kdb-text-primary);
}
.g-card__meta {
  margin-inline-start: auto;
  font-size: var(--kdb-size-caption);
  color: var(--kdb-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.g-card__comp {
  font-size: var(--kdb-size-micro);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-muted);
}

.g-empty { color: var(--kdb-text-muted); padding-block: var(--kdb-space-loose); }

/* ---------- the modal -------------------------------------- */

.g-modal[hidden] { display: none; }
.g-modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  padding: var(--kdb-space-base);
  background: color-mix(in srgb, var(--kdb-text-primary) 92%, transparent);
  animation: g-fade var(--kdb-motion-draw) var(--kdb-motion-curve) both;
}
@keyframes g-fade { from { opacity: 0 } to { opacity: 1 } }

.g-modal__sheet {
  width: min(960px, 100%);
  max-height: 100%;
  overflow: auto;
  background: var(--kdb-page-ground);
  padding: var(--kdb-space-base);
  animation: g-rise var(--kdb-motion-draw) var(--kdb-motion-curve) both;
}
@keyframes g-rise {
  from { opacity: 0; transform: translateY(var(--kdb-space-snug)) }
  to   { opacity: 1; transform: none }
}
/* A stills set shows the photograph where the player would be. */
/* A cutout has no background of its own, so it is contained on the surface
   rather than cropped to fill the frame the way a still from a clip is. */
.g-card__frame--cutout { background: var(--kdb-surface-sunken); }
.g-card__frame--cutout img,
.g-card__frame--cutout video { object-fit: contain; padding: 4%; }
.g-modal__img--cutout { background: var(--kdb-surface-sunken); padding: 3%; }

.g-modal__img {
  display: block;
  width: 100%;
  max-height: 68vh;
  object-fit: contain;
  background: var(--kdb-surface-sunken);
}
.g-modal__video {
  width: 100%;
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--kdb-text-primary);
}
.g-modal__head {
  display: flex;
  align-items: baseline;
  gap: var(--kdb-space-snug);
  margin-block-start: var(--kdb-space-snug);
  flex-wrap: wrap;
}
.g-modal__title {
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-head), "wght" var(--kdb-wght-heavy);
  font-size: var(--kdb-size-head);
  line-height: var(--kdb-leading-head);
  letter-spacing: var(--kdb-track-head);
  margin: 0;
}
.g-modal__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kdb-space-base);
  margin-block-start: var(--kdb-space-snug);
  padding-block-start: var(--kdb-space-snug);
  border-block-start: var(--kdb-rule-divide) solid var(--kdb-rule-divide-ink);
}
.g-fact { display: flex; flex-direction: column; gap: 2px; }
.g-fact__k {
  font-size: var(--kdb-size-micro);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-muted);
}
.g-fact__v {
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wght" var(--kdb-wght-medium);
  font-size: var(--kdb-size-small);
  color: var(--kdb-text-primary);
  font-variant-numeric: tabular-nums;
}
.g-modal__nav { display: flex; gap: var(--kdb-space-tight); margin-inline-start: auto; }
.g-modal__btn {
  font-family: var(--kdb-family-archivo);
  font-size: var(--kdb-size-label);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-primary);
  background: none;
  border: var(--kdb-rule-divide) solid var(--kdb-border-hairline);
  padding: var(--kdb-tag-pad-y) var(--kdb-tag-pad-x);
  cursor: pointer;
}
.g-modal__btn:hover { border-color: var(--kdb-accent-mark); }
.g-modal__btn[disabled] { opacity: 0.35; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .g-card, .g-modal, .g-modal__sheet { animation: none; }
  .g-card__frame video { transition: none; }
}

/* ---------- watch all ---------------------------------------
   The set the filters produced, played end to end. The control
   lives with the filters because that is what it acts on, and it
   carries the count so it is obvious what "all" currently means.
   ------------------------------------------------------------ */

.g-watch {
  display: inline-flex;
  align-items: center;
  gap: var(--kdb-space-tight);
  font-family: var(--kdb-family-archivo);
  font-variation-settings: "wdth" var(--kdb-wdth-text), "wght" var(--kdb-wght-medium);
  font-size: var(--kdb-size-small);
  color: var(--kdb-text-inverse);
  background: var(--kdb-border-strong);
  border: var(--kdb-rule-divide) solid var(--kdb-border-strong);
  padding: var(--kdb-space-hair) var(--kdb-space-snug);
  cursor: pointer;
  transition: background var(--kdb-motion-tick) var(--kdb-motion-curve),
              border-color var(--kdb-motion-tick) var(--kdb-motion-curve);
}
.g-watch:hover { background: var(--kdb-accent-text); border-color: var(--kdb-accent-text); }
.g-watch:focus-visible { outline: 2px solid var(--kdb-accent-mark); outline-offset: 3px; }
.g-watch[disabled] { opacity: 0.4; cursor: default; }
/* A drawn triangle rather than a glyph — ▶ arrives at a different
   size in every family and sits off the baseline. */
.g-watch__tri {
  width: 0; height: 0;
  border-inline-start: 7px solid currentColor;
  border-block: 5px solid transparent;
}
.g-watch__n { font-variant-numeric: tabular-nums; opacity: 0.7; }

.g-modal__stage { position: relative; }
.g-modal__pos {
  font-size: var(--kdb-size-caption);
  color: var(--kdb-text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Where you are in the sequence, under the picture. One hairline
   track, one accent fill — the same two values the cards use. */
.g-modal__bar {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 3px;
  background: var(--kdb-border-hairline);
}
.g-modal__bar > span {
  display: block;
  block-size: 100%;
  width: 0;
  background: var(--kdb-accent-mark);
  transition: width var(--kdb-motion-tick) linear;
}
.g-modal__btn--go {
  border-color: var(--kdb-border-strong);
  background: var(--kdb-border-strong);
  color: var(--kdb-text-inverse);
}
.g-modal__btn--go:hover { background: var(--kdb-accent-text); border-color: var(--kdb-accent-text); }
.g-modal__btn--go.is-on { background: var(--kdb-accent-mark); border-color: var(--kdb-accent-mark); }

/* ---------- tag groups --------------------------------------
   A group is a set of answers to one question, so it reads as one
   block with its own quiet label and behaves like radios. Between
   groups the filter ANDs, which is where the combinations are.
   ------------------------------------------------------------ */
.g-taggroup { display: flex; flex-direction: column; gap: var(--kdb-space-hair); }
.g-taggroup__label {
  font-size: var(--kdb-size-micro);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-muted);
}
/* The facet selects are generated, so they need their own row rather than
   each sitting in the page's grid. */
.g-facets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kdb-space-snug) var(--kdb-space-base);
  align-items: end;
}
.g-facets .g-field { margin: 0; }

#f-tags { display: flex; flex-wrap: wrap; gap: var(--kdb-space-base); }

/* ---------- canvas view -------------------------------------
   A pannable field of tiles instead of a page of rows. The idea
   is Jorge Capillo's infinite-layers-grid (MIT) — a grid split
   across depth layers that travel at different rates — rebuilt
   on DOM transforms rather than WebGL, because 108 clips do not
   need a scene graph and this build has no React in it.

   Filters still decide WHAT is on the field; the field only
   decides how you move through it.
   ------------------------------------------------------------ */

#canvas {
  position: relative;
  overflow: hidden;
  height: 70vh;            /* a starting value; goals-canvas.js fits it to the window */
  background: var(--kdb-surface-sunken);
  border-block: var(--kdb-rule-divide) solid var(--kdb-rule-divide-ink);
  cursor: grab;
  touch-action: none;
  contain: strict;
}
#canvas.is-dragging { cursor: grabbing; }

/* One field. Tiles are positioned in screen space every frame — the depth is in
   how far each layer travels, not in a stack of transformed parents. */
#canvas-plane { position: absolute; inset: 0; }

.c-tile {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  margin: 0;
  transform-origin: 0 0;
  will-change: transform;
}
/* Every tile is fully opaque. The far layers are smaller and slower — reading
   distance as transparency would make half the set look like it was loading. */
.c-tile__frame {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--kdb-neutral-20);
  border: var(--kdb-rule-divide) solid transparent;
  transition: border-color var(--kdb-motion-tick) var(--kdb-motion-curve);
}
.c-tile img, .c-tile video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.c-tile video { opacity: 0; transition: opacity var(--kdb-motion-draw) var(--kdb-motion-curve); }
.c-tile.is-playing video { opacity: 1; }
.c-tile:hover .c-tile__frame { border-color: var(--kdb-accent-mark); }

/* The label sits under the frame, always — a caption, not an overlay you have
   to hover or zoom into to read. */
.c-tile__cap {
  display: flex;
  gap: var(--kdb-space-tight);
  padding-block-start: var(--kdb-space-hair);
  font-size: var(--kdb-size-caption);
  line-height: 1.2;
  color: var(--kdb-text-primary);
  white-space: nowrap;
}
.c-tile__cap .d { margin-inline-start: auto; opacity: .6; font-variant-numeric: tabular-nums; }

/* ---------- globe view --------------------------------------
   The filtered set on one sphere: Fibonacci-spiral placement,
   tiles that billboard toward you, and a filter that re-packs
   the surface instead of clearing a page. After Matthew
   Greenberg's shoe-finder (MIT) — whose "3D" is likewise planes
   that face the camera, which is why this needs no WebGL.
   ------------------------------------------------------------ */

#globe {
  position: relative;
  overflow: hidden;
  height: 70vh;            /* goals-globe.js fits it to the window */
  background: var(--kdb-surface-sunken);
  border-block: var(--kdb-rule-divide) solid var(--kdb-rule-divide-ink);
  cursor: grab;
  touch-action: none;
  contain: strict;
}
#globe.is-dragging { cursor: grabbing; }
#globe-stage { position: absolute; inset: 0; }

.gl-tile {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  margin: 0;
  transform-origin: 0 0;
  will-change: transform, opacity;
}
/* No frame rule: on a sphere a hairline around every clip turned the whole
   thing into a mesh of boxes. The clip is its own edge. */
.gl-tile__frame {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--kdb-neutral-20);
}
.gl-tile img, .gl-tile video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.gl-tile video { opacity: 0; transition: opacity var(--kdb-motion-draw) var(--kdb-motion-curve); }
.gl-tile.is-playing video { opacity: 1; }
/* Round the back: still there, but not something you can hit by accident. */
.gl-tile.is-back { pointer-events: none; filter: saturate(.55); }
/* Micrographic, the way a broadcast card annotates a replay: the index hard
   left, the opponent hard right, above the clip and nothing else. Small enough
   to read as texture across a globe of 108 and still legible on the front. */
.gl-tile__cap {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--kdb-space-tight);
  padding-block-end: 2px;
  /* Set in px, not a token: the whole tile is scaled by the sphere, so this is
     the size at scale 1 and the zoom does the rest. Small enough that a globe
     of 108 reads as texture, and legible the moment you zoom into it. */
  font-size: 7px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--kdb-text-primary);
  white-space: nowrap;
}
.gl-tile.is-back .gl-tile__cap { visibility: hidden; }
.gl-tile__cap .n { font-variant-numeric: tabular-nums; opacity: .55; }
.gl-tile__cap .o { overflow: hidden; text-overflow: ellipsis; }

.c-hud button[aria-pressed="true"] {
  background: var(--kdb-text-inverse);
  color: var(--kdb-text-primary);
}

/* The one piece of chrome the plane needs: where you are, and a way back. */
.c-hud {
  position: absolute;
  inset-block-end: var(--kdb-space-snug);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--kdb-space-tight);
  background: color-mix(in srgb, var(--kdb-text-primary) 88%, transparent);
  color: var(--kdb-text-inverse);
  padding: var(--kdb-space-hair) var(--kdb-space-tight);
  font-size: var(--kdb-size-caption);
  white-space: nowrap;
  z-index: 2;
}
/* The hint is for a first visit, not for a narrow window. */
@media (max-width: 62rem) { .c-hud__hint { display: none; } }
.c-hud button {
  font: inherit;
  font-size: var(--kdb-size-label);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-inverse);
  background: none;
  border: var(--kdb-rule-divide) solid color-mix(in srgb, var(--kdb-text-inverse) 40%, transparent);
  padding: 2px var(--kdb-space-tight);
  cursor: pointer;
}
.c-hud button:hover { border-color: var(--kdb-text-inverse); }
.c-hud .sep { opacity: .4; }

/* In canvas mode the page itself must not scroll — the thing you drag is the
   plane, and a page sliding behind it makes the gesture ambiguous. */
body.is-canvas { overflow: hidden; }
/* The plane wants the room the intro was using. The deck explains the page on
   arrival; by the time you have switched views you have read it. */
body.is-canvas .g-deck { display: none; }
body.is-canvas .k-page > header.k-section { padding-block-end: 0; margin-block-end: 0; }
body.is-canvas .g-controls { margin-block-end: var(--kdb-space-snug); }

.g-viewtoggle { display: inline-flex; }
.g-viewtoggle button {
  font-family: var(--kdb-family-archivo);
  font-size: var(--kdb-size-label);
  letter-spacing: var(--kdb-track-caps);
  text-transform: uppercase;
  color: var(--kdb-text-secondary);
  background: transparent;
  border: var(--kdb-rule-divide) solid var(--kdb-border-hairline);
  padding: var(--kdb-tag-pad-y) var(--kdb-tag-pad-x);
  cursor: pointer;
}
.g-viewtoggle button + button { border-inline-start: 0; }
.g-viewtoggle button[aria-pressed="true"] {
  background: var(--kdb-border-strong);
  border-color: var(--kdb-border-strong);
  color: var(--kdb-text-inverse);
}
