/* ds-honeycomb-editor-rs — demo page styles.
 *
 * Plain CSS the repo owns. No framework, no npm, no PatternFly: the sibling
 * ds-catalog-browser-ui takes those and this repo deliberately does not, so
 * everything below is written out rather than imported.
 *
 * Group colours are validated values, and each is paired with a stroke that
 * carries the same distinction at a much higher contrast. Colour is never the
 * only encoding: every tile prints its group's NAME underneath its own label,
 * and the refusal is texture and motion before it is red.
 */

:root {
    color-scheme: light dark;

    --hc-bg:        #fbfaf7;
    --hc-surface:   #ffffff;
    --hc-ink:       #1b1a17;
    --hc-ink-2:     #6b6a66;
    --hc-line:      #ddd9d0;

    --hc-cell:      #f1f0ec;
    --hc-cell-line: #d8d6cf;

    /* slot 0 = ungrouped, then one pair per group ordinal. */
    --hc-slot-0:      #6b6a66;  --hc-slot-0-fill: #f1f0ec;
    --hc-slot-1:      #2a78d6;  --hc-slot-1-fill: #dee9f6;
    --hc-slot-2:      #1baf7a;  --hc-slot-2-fill: #dcf1e9;
    --hc-slot-3:      #eda100;  --hc-slot-3-fill: #faefd8;

    /* Never themed. A refusal means the same thing in both modes. */
    --hc-refuse:      #d03b3b;
    --hc-refuse-wash: #f6e1e0;
}

@media (prefers-color-scheme: dark) {
    :root {
        --hc-bg:        #17171a;
        --hc-surface:   #1e1e22;
        --hc-ink:       #ecebe6;
        --hc-ink-2:     #a6a49c;
        --hc-line:      #33323a;

        --hc-cell:      #26262b;
        --hc-cell-line: #3a3a42;

        --hc-slot-0:      #a6a49c;  --hc-slot-0-fill: #262624;
        --hc-slot-1:      #3987e5;  --hc-slot-1-fill: #1e2936;
        --hc-slot-2:      #199e70;  --hc-slot-2-fill: #1a2c25;
        --hc-slot-3:      #c98500;  --hc-slot-3-fill: #332916;

        --hc-refuse-wash: #341f1e;
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    padding: 0 1.25rem 3rem;
    background: var(--hc-bg);
    color: var(--hc-ink);
    font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ------------------------------------------------------------------ header */

.hc-head {
    display: flex; flex-wrap: wrap; gap: 1rem;
    align-items: flex-start; justify-content: space-between;
    max-width: 78rem; margin: 0 auto; padding: 1.75rem 0 1rem;
    border-bottom: 1px solid var(--hc-line);
}
.hc-head h1 { margin: 0; font-size: 1.5rem; letter-spacing: -0.01em; }
.hc-head__tag {
    margin-left: .6rem; padding: .15rem .5rem; border-radius: 999px;
    background: var(--hc-slot-1-fill); color: var(--hc-slot-1);
    font-size: .7rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; vertical-align: .25em;
}
.hc-head__sub { margin: .35rem 0 0; color: var(--hc-ink-2); }
.hc-head__repo { color: var(--hc-slot-1); text-decoration: none; font-weight: 600; }
.hc-head__repo:hover { text-decoration: underline; }

/* --------------------------------------------------------------- try-these */

.hc-try {
    max-width: 78rem; margin: 1.1rem auto 0; padding: 0; list-style: none;
    display: grid; gap: .5rem;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    counter-reset: hc-step;
}
.hc-try li {
    counter-increment: hc-step;
    background: var(--hc-surface); border: 1px solid var(--hc-line);
    border-radius: 8px; padding: .6rem .7rem .6rem 2.2rem;
    position: relative; font-size: .9rem;
}
.hc-try li::before {
    content: counter(hc-step);
    position: absolute; left: .6rem; top: .6rem;
    width: 1.25rem; height: 1.25rem; border-radius: 50%;
    background: var(--hc-slot-1); color: #fff;
    font-size: .72rem; font-weight: 700;
    display: grid; place-items: center;
}

.hc-noscript {
    max-width: 78rem; margin: 1rem auto 0; padding: .7rem .9rem;
    border-left: 4px solid var(--hc-slot-3); border-radius: 4px;
    background: var(--hc-slot-3-fill); color: var(--hc-ink);
}

/* ------------------------------------------------------------------ layout */

.hc-main {
    max-width: 78rem; margin: 1.25rem auto 0;
    display: grid; gap: 1.25rem;
    grid-template-columns: minmax(0, 1fr) minmax(20rem, 26rem);
    align-items: start;
}
@media (max-width: 60rem) {
    .hc-main { grid-template-columns: minmax(0, 1fr); }
}

.hc-board-pane, .hc-ttl-pane {
    background: var(--hc-surface); border: 1px solid var(--hc-line);
    border-radius: 10px; padding: .85rem;
}
/* A COLUMN NARROWER THAN THE BOARD SCROLLS, IT DOES NOT SHRINK THE BOARD PAST
   READING. `.hc-board-scroll`, just inside this pane, carries a min-width in
   px computed by `natural_size` (see `demo/src/lib.rs`) from the diagram
   actually on screen -- so this rule only has to say what happens when that
   child is wider than its parent, never guess how wide that might be. */
.hc-board-pane { overflow-x: auto; }

/* ------------------------------------------------------------------- board */

/* The component renders ONE <svg> and no CSS of its own: every rule below is
   the host's, matched on the class names the component documents. That is the
   seam -- swapping this file changes how the diagram looks and nothing about
   what a drop is allowed to do. */

.hc-board {
    display: block; width: 100%; height: auto;
    /* NOT touch-action HERE ANY MORE -- it is inline on the component's own
       <svg> (`manipulation`, not `none`: see that style's own comment in
       `honeycomb-yew/src/lib.rs`), and an inline style always wins the
       cascade over a class selector like this one. A `none` here used to be
       dead weight this file disagreed with the moment the two were compared
       side by side; better to say plainly that this file no longer has an
       opinion, which `-webkit-user-select`/`user-select` below still do. */
    -webkit-user-select: none; user-select: none;
}
.hc-board:focus-visible { outline: 3px solid var(--hc-slot-1); outline-offset: 2px; }
.hc-board.is-refused { cursor: not-allowed; }

/* The aria-live region the component keeps inside the SVG. It carries
   fill="none" already, so it paints nothing; this only takes it out of the way
   of the pointer. NOT display:none -- a hidden live region is not announced,
   which is the whole reason it exists. */
.hc-live { pointer-events: none; font-size: 1px; }

/* The empty lattice behind everything. fill="none" on purpose: it is a hint
   about where the cells are, and a filled one would compete with the grounds. */
.hc-frame__cell { fill: none; stroke: var(--hc-cell-line); stroke-width: 1.2; }

/* ------------------------------------------------------------- the grounds */

/* A region is drawn TWICE from the same grown hexagons: a stroke pass, then a
   fill pass over the top. Only the perimeter the union does not cover survives,
   which is what makes one continuous region out of n separate hexagons -- and
   it follows the members for free, because the paths are re-derived from their
   cells on every render. */
.hc-ground__edge { fill: none; stroke: var(--hc-slot-0); stroke-width: 2.5; }
.hc-ground__fill { fill: var(--hc-slot-0-fill); stroke: none; }
/* NO `pointer-events: none` HERE ANY MORE, and that is the gesture rather than
   a tidy-up. A district's heading is the handle you grab to move the district:
   the ground's own fringe past the tiles is about a sixth of a hexagon wide, so
   the label is the part of the region that is comfortably pressable. */
.hc-ground__label {
    fill: var(--hc-ink-2); font-size: 12px; font-weight: 700;
    text-anchor: middle; letter-spacing: .04em;
}
/* A GROUP'S NOTE, printed one line under its heading — "deployed once per
   participant", a caveat, whatever a district's own hive:note says. Lighter
   and smaller than the heading it sits under: the heading is the name and the
   grab handle, the note is a caption, and the two should never compete for a
   reader's eye first. `pointer-events: none` on purpose: the note is not part
   of the drag handle `.hc-ground__label` doubles as, and a note that happened
   to sit over a neighbouring hexagon must not steal that hexagon's own press. */
.hc-ground__note {
    fill: var(--hc-ink-2); font-size: 9.5px; font-weight: 500;
    text-anchor: middle; letter-spacing: .02em; pointer-events: none;
}
[data-slot="1"].hc-ground .hc-ground__edge { stroke: var(--hc-slot-1); }
[data-slot="1"].hc-ground .hc-ground__fill { fill:   var(--hc-slot-1-fill); }
[data-slot="2"].hc-ground .hc-ground__edge { stroke: var(--hc-slot-2); }
[data-slot="2"].hc-ground .hc-ground__fill { fill:   var(--hc-slot-2-fill); }
[data-slot="3"].hc-ground .hc-ground__edge { stroke: var(--hc-slot-3); }
[data-slot="3"].hc-ground .hc-ground__fill { fill:   var(--hc-slot-3-fill); }

/* A split group is REPORTED, never repaired: the dashes say the region is in
   pieces, and the label says how many.

   Deliberately soft. Dragging one tile out of a district is now the ORDINARY
   gesture -- a press on a hexagon moves that hexagon -- so this is the state a
   reader will see most often, and it has to read as information rather than as
   alarm. */
.hc-ground.is-fractured .hc-ground__edge { stroke-dasharray: 7 5; }

/* The group is draggable, and hover is the only thing that can say so BEFORE
   the press. It also matters where two grown regions merge: the highlight is
   what shows which of the two a press is about to reach. */
.hc-group { cursor: grab; }
.hc-ground.is-hovered .hc-ground__edge { stroke-width: 4; }
.hc-ground.is-held .hc-ground__edge { stroke-width: 4; stroke-dasharray: none; }
/* THE RING IS THE BROWSER'S OWN OUTLINE, and the previous attempt was not drawn
   at all: `filter: drop-shadow()` takes offsets, a blur and a colour — unlike
   `box-shadow` it has NO spread radius — so `drop-shadow(0 0 0 2px …)` was a
   syntax error, the declaration was dropped, and the `outline: none` beside it
   meant a focused group region showed nothing whatsoever. */
.hc-group:focus-visible {
    outline: 3px solid var(--hc-ink-2);
    outline-offset: 2px;
}
.hc-group:focus-visible .hc-ground__edge { stroke-width: 4; }

/* -------------------------------------------------------------------- tiles */

.hc-tile { cursor: grab; }
.hc-tile__hex {
    fill: var(--hc-slot-0-fill); stroke: var(--hc-slot-0); stroke-width: 2;
}
.hc-tile__label {
    fill: var(--hc-ink); font-size: 15px; font-weight: 600;
    text-anchor: middle; pointer-events: none;
}
/* Group identity is never colour-alone: the name is printed on every tile. */
.hc-tile__group {
    fill: var(--hc-ink-2); font-size: 11px; text-anchor: middle;
    pointer-events: none;
}

[data-slot="1"] .hc-tile__hex { fill: var(--hc-slot-1-fill); stroke: var(--hc-slot-1); }
[data-slot="2"] .hc-tile__hex { fill: var(--hc-slot-2-fill); stroke: var(--hc-slot-2); }
[data-slot="3"] .hc-tile__hex { fill: var(--hc-slot-3-fill); stroke: var(--hc-slot-3); }

.hc-tile.is-selected .hc-tile__hex { stroke-width: 4; }

/* --------------------------------------------------------------- the drag */

/* THE REAL TILE DOES NOT MOVE. It stays at its committed cell, faded, and a
   ghost is drawn at the snapped candidate. Escape then has something to restore
   to, the origin stays visible -- "where it came from" is half of what the user
   is deciding -- and an illegal candidate can be drawn AS illegal, which is
   impossible if it is drawn as the tile itself. */
.hc-tile.is-moving { cursor: grabbing; opacity: .35; }
.hc-tile--ghost { pointer-events: none; }
.hc-tile--ghost .hc-tile__hex {
    stroke-width: 3;
    filter: drop-shadow(0 6px 10px rgb(0 0 0 / .28));
}

/* ------------------------------------------------------------- the refusal */

/* Colour cannot carry this on its own: the status red against the categorical
   orange is below the perceptual-distance floor for normal vision, never mind
   protanopia. So a refused drop is TEXTURE (hatch), MOTION (the status shake)
   and WORDS (the status line names the blocking tile), with red only
   reinforcing. And it appears BEFORE the user releases -- a refusal discovered
   on release is discovered too late. */
.hc-hatch-bg   { fill: var(--hc-refuse-wash); }
.hc-hatch-line { stroke: var(--hc-refuse); stroke-width: 2; opacity: .5; }

.hc-tile--ghost.is-refused .hc-tile__hex {
    fill: none;
    stroke: var(--hc-refuse); stroke-width: 2; stroke-dasharray: 6 4;
    filter: none;
}
.hc-tile--ghost.is-refused .hc-tile__label,
.hc-tile--ghost.is-refused .hc-tile__group { fill: var(--hc-refuse); }

/* The tiles in the way are outlined, from the evidence the rejection carries:
   "you can't drop here" leaves the host nothing to point at. */
.hc-tile.is-blocking .hc-tile__hex { stroke: var(--hc-refuse); stroke-width: 3; }
.hc-tile__bar { fill: url(#hc-hatch-blocked); stroke: none; pointer-events: none; }

/* ABOUT TO BE DISPLACED BY A SWAP, which is NOT a refusal and must not be
   painted like one. The tile is moving because the drop is being accepted, so
   this is a texture -- dashes and a little transparency -- and never the refusal
   red. A user who sees a second hexagon move and a red outline at the same time
   concludes the editor malfunctioned. */
.hc-tile.is-displacing .hc-tile__hex {
    stroke-dasharray: 3 4; stroke-width: 2.4; opacity: .55;
}

.hc-status {
    margin: .7rem 0 .15rem; padding: .5rem .7rem;
    border-radius: 6px; font-size: .92rem; font-weight: 500;
    border-left: 4px solid transparent;
}
.hc-status--rest { background: var(--hc-cell); color: var(--hc-ink-2); }
.hc-status--refused {
    background: var(--hc-refuse-wash); color: var(--hc-refuse);
    border-left-color: var(--hc-refuse); font-weight: 600;
    animation: hc-refuse-shake 240ms ease-in-out 3;
}
@keyframes hc-refuse-shake {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-3px); }
    75%      { transform: translateX(3px); }
}
.hc-status--warning {
    background: var(--hc-slot-3-fill); color: var(--hc-ink);
    border-left-color: var(--hc-slot-3);
}
/* NO ANIMATION ON THE BOARD ANYWHERE -- the ghost snaps and nothing tweens --
   so this has one thing to turn off rather than a branch through the editor. */
@media (prefers-reduced-motion: reduce) {
    .hc-status--refused { animation: none; }
}

/* -------------------------------------------------------------- turtle pane */

.hc-ttl-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.hc-ttl-head h2 { margin: 0; font-size: .95rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.hc-ttl-count { color: var(--hc-ink-2); font-size: .8rem; }

.hc-ttl-actions { display: flex; gap: .5rem; margin: .6rem 0; flex-wrap: wrap; }
.hc-btn {
    appearance: none; cursor: pointer; text-decoration: none;
    border: 1px solid var(--hc-line); border-radius: 6px;
    background: var(--hc-bg); color: var(--hc-ink);
    padding: .35rem .7rem; font: inherit; font-size: .85rem; font-weight: 600;
}
.hc-btn:hover { border-color: var(--hc-slot-1); color: var(--hc-slot-1); }
.hc-btn:focus-visible { outline: 2px solid var(--hc-slot-1); outline-offset: 2px; }

.hc-ttl {
    margin: 0; max-height: 34rem; overflow: auto;
    background: var(--hc-bg); border: 1px solid var(--hc-line); border-radius: 6px;
    padding: .7rem; tab-size: 2;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .78rem; line-height: 1.5;
}

/* --------------------------------------------------------- listing + foot */

/* Rendered by the generator, so it is readable with no JavaScript at all, and
   doubles as the non-colour route to the same information. */
.hc-listing {
    max-width: 78rem; margin: 1.25rem auto 0;
    background: var(--hc-surface); border: 1px solid var(--hc-line);
    border-radius: 10px; padding: .85rem;
}
.hc-listing summary { cursor: pointer; font-weight: 600; }
.hc-listing table { width: 100%; border-collapse: collapse; margin-top: .7rem; font-size: .9rem; }
.hc-listing th, .hc-listing td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid var(--hc-line); }
.hc-listing th { color: var(--hc-ink-2); font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; }

.hc-foot {
    max-width: 78rem; margin: 1.5rem auto 0; padding-top: 1rem;
    border-top: 1px solid var(--hc-line);
    color: var(--hc-ink-2); font-size: .85rem;
}
.hc-foot code { font-size: .8rem; word-break: break-all; }
.hc-foot a { color: var(--hc-slot-1); }

/* ---------------------------------------------------------------- palette */

/* A DRAWER, not a rail: the board is the thing on this page and a column beside
   it would take width from the only thing worth looking at. Open by default
   while the bench has anything in it, because a palette nobody opens is a
   feature nobody finds. */
.hc-palette {
    margin: 0 0 1rem; padding: .6rem .8rem;
    border-radius: 10px; background: var(--hc-cell);
    box-shadow: inset 0 0 0 1px var(--hc-line);
}
.hc-palette > summary { cursor: pointer; font-weight: 700; color: var(--hc-ink); }
.hc-palette__count { margin-left: .5rem; font-weight: 500; color: var(--hc-ink-2); }
.hc-palette__note { margin: .5rem 0 .6rem; font-size: .85rem; color: var(--hc-ink-2); }
.hc-palette__list { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; list-style: none; }

/* `touch-action: manipulation`, NOT `none`. A drawer of thirty chips has to be
   scrollable with a finger, and `none` on the chips means the scroll starts on
   one and goes nowhere. The cost is that drag-from-palette is a pointer gesture;
   on touch a chip is tap-to-arm and the board is tap-to-place, which is the same
   path the keyboard uses. */
.hc-chip {
    touch-action: manipulation; cursor: grab;
    padding: .3rem .7rem; border: 0; border-radius: 999px;
    background: var(--hc-slot-0-fill); color: var(--hc-ink);
    font: inherit; font-size: .85rem; font-weight: 600;
    box-shadow: inset 0 0 0 1.5px var(--hc-slot-0);
}
.hc-chip[aria-pressed="true"] {
    background: var(--hc-slot-0); color: #fff;
}
.hc-chip:focus-visible { outline: 3px solid var(--hc-ink-2); outline-offset: 2px; }

/* THE EMPTY CELLS BECOME TARGETS, and say so. This is the only affordance that
   distinguishes "a chip is armed" from "nothing is happening" on the board
   itself. */
.hc-frame.is-armed .hc-frame__cell { stroke: var(--hc-slot-1); stroke-width: 1.4; }

/* ---------------------------------------------------------------- links */

/* Lines sit between the grounds and the tiles: above the regions, because a
   line under a coloured ground is a line nobody drew; below the hexagons,
   because a straight route crosses cells by design and passing BEHIND one is
   the whole reason that routing is usable. */
.hc-link__line {
    stroke: var(--hc-ink-2);
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* Every terminator: the plain arrowhead a line into a building gets, and the
   crossbar-plus-arrowhead a line into a DISTRICT gets. Same shape and same
   size for the head in both -- see the two <marker> definitions in src/lib.rs
   -- so the bar is the only difference in FORM a reader has to read. */
.hc-arrow { fill: var(--hc-ink-2); }

/* A LINE THAT ENDS ON A WHOLE DISTRICT, AND WHY IT NEEDS SAYING.

   Both kinds of line stop in the same place. The component trims a stroke back
   to 0.92r from the ANCHOR CELL's centre whichever kind of end it is, and a
   district's ground is its members' hexagons grown to 1.16r -- so a line to a
   district finishes INSIDE the coloured region, a hair off one member's
   hexagon, exactly where a line to that one member would finish. Nothing in
   the geometry distinguishes them, and a reader looking at the greenway sees a
   stroke ending at Orchard and concludes the Museum is connected to Orchard.
   It is connected to the Green Belt, and which building it touches changes the
   moment the district moves.

   So the terminator carries the distinction (see the two <marker> definitions
   in src/lib.rs, and `terminators` beside them) and these classes carry
   whatever the rest of the stroke needs. A <marker> is a shared definition and
   cannot be restyled from the element that references it, which is the whole
   reason the classes exist alongside it.

   THE LINE ITSELF IS DELIBERATELY NOT RECOLOURED OR DASHED. Dashes are already
   spoken for -- `.hc-ground.is-fractured` uses them for a split district -- and
   a second colour would compete with the ground palette the districts
   themselves are drawn in. The terminator is the one change, which is also
   what keeps the asymmetric lines readable: on the greenway a reader sees a
   district cap and a building head in ONE stroke and can tell which is which
   without a legend. */
/* THE DISTRICT TERMINATOR IS DARKER THAN THE LINE, and that is the one paint
   decision here. It is the only terminator that lands on a COLOURED ground:
   the crossbar falls on or near the region's own 2.5px edge stroke, in the
   district's own hue, and a grey bar on a blue edge on a blue wash is a mark a
   reader has to hunt for. --hc-ink carries in both themes over all four
   grounds. */
.hc-arrow--district { fill: var(--hc-ink); }

/* NOTHING HANGS OFF THESE TWO CLASSES TODAY, ON PURPOSE, and the reason is
   worth writing down because the obvious edit is a trap: a marker's size is a
   multiple of the referencing path's STROKE-WIDTH (markerUnits defaults to
   strokeWidth), so `.hc-link.is-to-district .hc-link__line { stroke-width: … }`
   would silently rescale the terminator and destroy the comparison the
   terminator exists to support -- a reader is meant to see the SAME arrowhead
   with a bar added, not a bigger one. Dashes are spoken for too
   (`.hc-ground.is-fractured`), and a second stroke colour would compete with
   the ground palette the districts themselves are drawn in.

   They are kept because they are the handle a host reading this page for the
   pattern needs: a <marker> is a shared definition and cannot be restyled from
   the element that references it, so a host that wants the rest of the stroke
   to react to a district end has nowhere else to hang the rule. */
.hc-link.is-from-district,
.hc-link.is-to-district { /* see above */ }

.hc-link__label {
    fill: var(--hc-ink-2);
    font-size: 10px;
    font-weight: 600;
    text-anchor: middle;
    paint-order: stroke;
    stroke: var(--hc-bg);
    stroke-width: 3;
    stroke-linejoin: round;
}
/* The rubber band while a line is being drawn is styled inline by the
   component, because it has to say whether the release will land. */

/* `hc-linkhit` IS THE COMPONENT'S OWN WRAPPER (finding 1), a real tab stop
   around whatever this file draws inside it -- the same relationship
   `hc-group` already has to `hc-ground`. Clicking or Tabbing to a line
   focuses this element, never `hc-link` itself, so the focus ring and the
   cursor affordance both belong on it. */
.hc-linkhit { cursor: pointer; }
.hc-linkhit:focus-visible { outline: 3px solid var(--hc-ink-2); outline-offset: 2px; }
/* THE PAINTED AFFORDANCE for `LinkView::focused`: a bolder, darker line so
   "Delete removes this one" is visible even where the browser's own focus
   ring is hard to see against a hex lattice. Not the refusal red -- nothing
   here is wrong, a line is just selected. */
.hc-link.is-focused .hc-link__line { stroke: var(--hc-ink); stroke-width: 3.5; }

/* The Link toggle is a MODE, so it has to look like one when it is on. */
.hc-btn.is-on {
    background: var(--hc-slot-1);
    color: #fff;
}

/* ------------------------------------------------------------ districts */

/* Below the board, the way the palette sits above it. Everything in here
   changes the DIAGRAM: a district's name, its ground and its note are terms
   this document owns. */
.hc-groups {
    margin: 1rem 0 0; padding: .6rem .8rem;
    border-radius: 10px; background: var(--hc-cell);
    box-shadow: inset 0 0 0 1px var(--hc-line);
}
.hc-groups > summary { cursor: pointer; font-weight: 700; color: var(--hc-ink); }
.hc-groups__count {
    margin-left: .5rem; padding: 0 .45rem;
    border-radius: 999px; background: var(--hc-slot-0-fill);
    font-weight: 600; font-size: .8rem; color: var(--hc-ink-2);
}
.hc-groups__table { width: 100%; border-collapse: collapse; margin: .6rem 0 .4rem; }
.hc-groups__table th {
    text-align: left; font-size: .72rem; text-transform: uppercase;
    letter-spacing: .06em; color: var(--hc-ink-2); font-weight: 700;
    padding: 0 .4rem .3rem 0;
}
.hc-groups__table td { padding: .18rem .4rem .18rem 0; vertical-align: middle; }
.hc-groups__table input[type="text"],
.hc-groups__table select,
.hc-groups__new input[type="text"] {
    padding: .25rem .45rem; border-radius: 6px;
    border: 1px solid var(--hc-line); background: #fff;
    font: inherit; font-size: .85rem; color: var(--hc-ink);
}
.hc-groups__table input[type="text"] { width: 100%; min-width: 7rem; }
/* An unnamed district is legal, so its box must not look like a mistake. */
.hc-groups__table input::placeholder { color: var(--hc-ink-2); opacity: .6; font-style: italic; }
.hc-groups__n { text-align: right; font-variant-numeric: tabular-nums; color: var(--hc-ink-2); }
.hc-btn--quiet {
    padding: .2rem .55rem; font-size: .78rem;
    background: transparent; color: var(--hc-ink-2);
    box-shadow: inset 0 0 0 1px var(--hc-line);
}
.hc-btn--quiet:hover:not(:disabled) { background: #fff; color: var(--hc-ink); }
.hc-btn:disabled { opacity: .45; cursor: default; }
.hc-groups__new { display: flex; gap: .4rem; align-items: center; margin: .5rem 0 .2rem; }
.hc-groups__member {
    display: flex; gap: .45rem; align-items: center;
    margin: .6rem 0 .1rem; padding-top: .55rem;
    border-top: 1px solid var(--hc-line);
    font-size: .85rem; color: var(--hc-ink);
}
.hc-groups__none { color: var(--hc-ink-2); }
.hc-groups__member select {
    padding: .25rem .45rem; border-radius: 6px;
    border: 1px solid var(--hc-line); background: #fff; font: inherit; font-size: .85rem;
}

/* Visible to a screen reader and to nobody else. */
.hc-sr {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; border: 0;
}
