/*
 * Poll block stylesheet (260806-vote). The component emits ONLY data
 * attributes; this sheet owns layout, the result bars and focus styling.
 * Served from /noon-poll.css and hoisted into the head by React's
 * <link precedence> dedup whenever a Poll renders — a page with no poll never
 * references it.
 *
 * Every rule is in the `noon` cascade layer, so operator `customCss`
 * (unlayered) beats it regardless of specificity and of hoist order — the FULL
 * rationale lives ONCE, in `noon-theme.css`.
 *
 * The result bar's width is driven by `data-percent`, one exact rule per
 * integer, rather than an inline `style` attribute — the renderer emits
 * attributes only. It was eleven decade steps until 260807; see the rule block
 * for why that was a defect and not just an approximation.
 */

@layer noon {
  [data-block="Poll"] {
    margin: calc(var(--noon-spacing-unit, 8px) * 4) 0;
  }

  [data-poll-question] {
    margin: 0 0 calc(var(--noon-spacing-unit, 8px) * 1);
  }

  [data-poll-status] {
    margin: 0 0 calc(var(--noon-spacing-unit, 8px) * 2);
    color: var(--noon-muted, #666);
    font-size: 0.9em;
  }

  [data-block="Poll"] fieldset {
    border: none;
    margin: 0;
    padding: 0;
  }

  /* The question is already an <h2> above; the legend repeats it for assistive
 * technology grouping the radios, so it is hidden visually rather than
 * duplicated on screen. Not `display:none` — that removes it from the
 * accessibility tree too, which is the entire reason it exists. */
  [data-block="Poll"] legend {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  [data-poll-option] {
    display: flex;
    align-items: center;
    gap: calc(var(--noon-spacing-unit, 8px) * 1);
    padding: calc(var(--noon-spacing-unit, 8px) * 1) 0;
    cursor: pointer;
  }

  [data-poll-suggested] {
    font-size: 0.75em;
    white-space: nowrap;
    color: var(--noon-muted, #666);
    border: 1px solid var(--noon-border, #ddd);
    border-radius: var(--noon-radius, 4px);
    padding: 0 0.4em;
  }

  /* ── ON A PHONE THE PILL BECOMES A SYMBOL ──
 *
 * "visitor suggested" is fourteen characters of nowrap sitting beside an option
 * label that is already competing for the row. On a narrow screen it pushed the
 * label out and broke the result row.
 *
 * The WORDS ARE NOT REMOVED — they are collapsed with `font-size: 0` and a mark
 * is drawn in their place. `display: none` or removing the text in the renderer
 * would take the phrase out of the accessibility tree too, so a screen-reader
 * user would lose the one thing that says this option came from a visitor. This
 * way the badge is a symbol to the eye and a sentence to a screen reader.
 *
 * THE MARK IS AN ASTERISK AND NOT A "+", which is what it was first written as.
 * `[data-poll-suggest] > summary::before` further down this sheet already draws
 * a "+" for the ADD-AN-OPTION toggle, and on a phone both are on screen at once
 * inside the same poll. One would have meant "do something", the other "this was
 * done by someone", in the same glyph, a few rows apart. An asterisk is the
 * footnote mark: it says this entry carries a qualification, and nothing about
 * it invites a tap. It sits high in its em box, which is what a footnote mark is
 * supposed to look like, so that is left alone rather than nudged with a
 * transform whose magic number could not be checked without a browser.
 *
 * `rem` and not `em` THROUGHOUT this block: the element is `font-size: 0`, and
 * `em` resolves against the element's OWN font size for every property except
 * font-size itself. So an `em` padding here computes to 0 and the "+" sits flush
 * against both borders, and an `em` font-size on the pseudo-element makes the
 * glyph vanish outright. Both read as a missing style rather than a unit bug.
 *
 * `line-height` is left as a UNITLESS number on purpose — a number is inherited
 * as a number and recomputed against each element's own font size, so the pill's
 * own strut is 0 while the "+" still gets 1.5 x 0.8rem and gives the badge its
 * height. A `line-height: 1.2rem` here would work too; a `1.2em` would not.
 */
  @media (max-width: 30rem) {
    [data-poll-suggested] {
      font-size: 0;
      padding: 0 0.35rem;
      line-height: 1.5;
    }

    [data-poll-suggested]::before {
      content: "*";
      font-size: 0.9rem;
      font-weight: 600;
    }
  }

  [data-block="Poll"] button {
    margin-top: calc(var(--noon-spacing-unit, 8px) * 2);
    padding: calc(var(--noon-spacing-unit, 8px) * 1) calc(var(--noon-spacing-unit, 8px) * 2);
    border: 1px solid var(--noon-border, #ddd);
    border-radius: var(--noon-radius, 4px);
    background: var(--noon-accent, #333);
    color: var(--noon-accent-contrast, #fff);
    cursor: pointer;
  }

  /* `font: inherit` and `accent-color` for these controls now come from the
 * SHARED base sheet (`noon-controls.css`, emitted by lib/controls.tsx) rather
 * than being repeated per block — they correct a browser default and bind a
 * theme token, which every control wants. What stays here is the sizing, which
 * IS a decision about this component: the option rows are a flex line, and the
 * box is sized in `em` so it tracks the inherited font instead of sitting at
 * the browser's fixed box beside larger text. */
  [data-block="Poll"] input:is([type="radio"], [type="checkbox"]) {
    width: 1.1em;
    height: 1.1em;
    /* The option row is a flex line; without this the box is squeezed by a long
   * label instead of the label wrapping. */
    flex: none;
    margin: 0;
  }

  [data-block="Poll"] :is(input, button):focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
  }

  [data-poll-note] {
    margin: calc(var(--noon-spacing-unit, 8px) * 1) 0 0;
    color: var(--noon-muted, #666);
    font-size: 0.85em;
  }

  /* ── results ── */

  [data-poll-results] {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  [data-poll-result] {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0 calc(var(--noon-spacing-unit, 8px) * 1);
    align-items: baseline;
    padding: calc(var(--noon-spacing-unit, 8px) * 1) 0;
  }

  /* The leading option, marked with ONE signal: weight.
 *
 * The first version of this marked it three ways — bold text, an accent bar for
 * the leader and a grey bar for everyone else. On a tie that meant most of the
 * list was emphasised and the two bar colours read as a category difference
 * ("what do the grey ones mean?") rather than as a ranking the numbers already
 * state. The bar length IS the comparison; colouring it too says the same thing
 * a third time.
 *
 * So every bar is the same colour and only the text thickens. No size change
 * either — a row that grew would make the winner's LENGTH look like data. */
  [data-poll-result][data-poll-leading] [data-poll-label],
  [data-poll-result][data-poll-leading] [data-poll-count] {
    font-weight: 600;
  }

  /* The label cell holds the option name AND its pill, so the pill sits beside
 * the name instead of becoming a grid row of its own. Wraps rather than
 * overflowing when the name is long. */
  /* biome-ignore lint/style/noDescendingSpecificity: the sheet is ordered by block narrative; specificity, not order, decides between these two */
  [data-poll-result] [data-poll-label] {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: calc(var(--noon-spacing-unit, 8px) * 1);
    min-width: 0;
  }

  [data-poll-bar] {
    grid-column: 1 / -1;
    display: block;
    height: 6px;
    border-radius: var(--noon-radius, 4px);
    background: var(--noon-border, #eee);
    overflow: hidden;
  }

  [data-poll-bar-fill] {
    display: block;
    height: 100%;
    background: var(--noon-accent, #333);
    width: 0;
  }

  /* ── EXACT WIDTHS, ONE RULE PER INTEGER ──
 *
 * This replaced eleven "decade" rules that used PREFIX matching
 * (`[data-percent^="5"]`), and those were not merely coarse — they were WRONG:
 * `^="5"` matches "5" as well as "50".."59", so an option holding 5% of the
 * vote rendered a HALF-FULL bar, and 7% rendered at 70%. On a poll where one
 * option runs away with it, every minority option was drawn roughly ten times
 * its real size. Found while reviewing the results view, not by a test.
 *
 * 101 exact rules is the honest fix within this component's constraint: the
 * renderer emits attributes only (no inline `style`, enforced by
 * `boundary-gates.test.ts`), so the width has to be selectable from the
 * attribute value. It costs about 4 KB in a sheet that only loads on pages
 * carrying a poll, which is a good trade for a bar that tells the truth.
 */
  [data-poll-bar-fill][data-percent="0"] {
    width: 0%;
  }
  [data-poll-bar-fill][data-percent="1"] {
    width: 1%;
  }
  [data-poll-bar-fill][data-percent="2"] {
    width: 2%;
  }
  [data-poll-bar-fill][data-percent="3"] {
    width: 3%;
  }
  [data-poll-bar-fill][data-percent="4"] {
    width: 4%;
  }
  [data-poll-bar-fill][data-percent="5"] {
    width: 5%;
  }
  [data-poll-bar-fill][data-percent="6"] {
    width: 6%;
  }
  [data-poll-bar-fill][data-percent="7"] {
    width: 7%;
  }
  [data-poll-bar-fill][data-percent="8"] {
    width: 8%;
  }
  [data-poll-bar-fill][data-percent="9"] {
    width: 9%;
  }
  [data-poll-bar-fill][data-percent="10"] {
    width: 10%;
  }
  [data-poll-bar-fill][data-percent="11"] {
    width: 11%;
  }
  [data-poll-bar-fill][data-percent="12"] {
    width: 12%;
  }
  [data-poll-bar-fill][data-percent="13"] {
    width: 13%;
  }
  [data-poll-bar-fill][data-percent="14"] {
    width: 14%;
  }
  [data-poll-bar-fill][data-percent="15"] {
    width: 15%;
  }
  [data-poll-bar-fill][data-percent="16"] {
    width: 16%;
  }
  [data-poll-bar-fill][data-percent="17"] {
    width: 17%;
  }
  [data-poll-bar-fill][data-percent="18"] {
    width: 18%;
  }
  [data-poll-bar-fill][data-percent="19"] {
    width: 19%;
  }
  [data-poll-bar-fill][data-percent="20"] {
    width: 20%;
  }
  [data-poll-bar-fill][data-percent="21"] {
    width: 21%;
  }
  [data-poll-bar-fill][data-percent="22"] {
    width: 22%;
  }
  [data-poll-bar-fill][data-percent="23"] {
    width: 23%;
  }
  [data-poll-bar-fill][data-percent="24"] {
    width: 24%;
  }
  [data-poll-bar-fill][data-percent="25"] {
    width: 25%;
  }
  [data-poll-bar-fill][data-percent="26"] {
    width: 26%;
  }
  [data-poll-bar-fill][data-percent="27"] {
    width: 27%;
  }
  [data-poll-bar-fill][data-percent="28"] {
    width: 28%;
  }
  [data-poll-bar-fill][data-percent="29"] {
    width: 29%;
  }
  [data-poll-bar-fill][data-percent="30"] {
    width: 30%;
  }
  [data-poll-bar-fill][data-percent="31"] {
    width: 31%;
  }
  [data-poll-bar-fill][data-percent="32"] {
    width: 32%;
  }
  [data-poll-bar-fill][data-percent="33"] {
    width: 33%;
  }
  [data-poll-bar-fill][data-percent="34"] {
    width: 34%;
  }
  [data-poll-bar-fill][data-percent="35"] {
    width: 35%;
  }
  [data-poll-bar-fill][data-percent="36"] {
    width: 36%;
  }
  [data-poll-bar-fill][data-percent="37"] {
    width: 37%;
  }
  [data-poll-bar-fill][data-percent="38"] {
    width: 38%;
  }
  [data-poll-bar-fill][data-percent="39"] {
    width: 39%;
  }
  [data-poll-bar-fill][data-percent="40"] {
    width: 40%;
  }
  [data-poll-bar-fill][data-percent="41"] {
    width: 41%;
  }
  [data-poll-bar-fill][data-percent="42"] {
    width: 42%;
  }
  [data-poll-bar-fill][data-percent="43"] {
    width: 43%;
  }
  [data-poll-bar-fill][data-percent="44"] {
    width: 44%;
  }
  [data-poll-bar-fill][data-percent="45"] {
    width: 45%;
  }
  [data-poll-bar-fill][data-percent="46"] {
    width: 46%;
  }
  [data-poll-bar-fill][data-percent="47"] {
    width: 47%;
  }
  [data-poll-bar-fill][data-percent="48"] {
    width: 48%;
  }
  [data-poll-bar-fill][data-percent="49"] {
    width: 49%;
  }
  [data-poll-bar-fill][data-percent="50"] {
    width: 50%;
  }
  [data-poll-bar-fill][data-percent="51"] {
    width: 51%;
  }
  [data-poll-bar-fill][data-percent="52"] {
    width: 52%;
  }
  [data-poll-bar-fill][data-percent="53"] {
    width: 53%;
  }
  [data-poll-bar-fill][data-percent="54"] {
    width: 54%;
  }
  [data-poll-bar-fill][data-percent="55"] {
    width: 55%;
  }
  [data-poll-bar-fill][data-percent="56"] {
    width: 56%;
  }
  [data-poll-bar-fill][data-percent="57"] {
    width: 57%;
  }
  [data-poll-bar-fill][data-percent="58"] {
    width: 58%;
  }
  [data-poll-bar-fill][data-percent="59"] {
    width: 59%;
  }
  [data-poll-bar-fill][data-percent="60"] {
    width: 60%;
  }
  [data-poll-bar-fill][data-percent="61"] {
    width: 61%;
  }
  [data-poll-bar-fill][data-percent="62"] {
    width: 62%;
  }
  [data-poll-bar-fill][data-percent="63"] {
    width: 63%;
  }
  [data-poll-bar-fill][data-percent="64"] {
    width: 64%;
  }
  [data-poll-bar-fill][data-percent="65"] {
    width: 65%;
  }
  [data-poll-bar-fill][data-percent="66"] {
    width: 66%;
  }
  [data-poll-bar-fill][data-percent="67"] {
    width: 67%;
  }
  [data-poll-bar-fill][data-percent="68"] {
    width: 68%;
  }
  [data-poll-bar-fill][data-percent="69"] {
    width: 69%;
  }
  [data-poll-bar-fill][data-percent="70"] {
    width: 70%;
  }
  [data-poll-bar-fill][data-percent="71"] {
    width: 71%;
  }
  [data-poll-bar-fill][data-percent="72"] {
    width: 72%;
  }
  [data-poll-bar-fill][data-percent="73"] {
    width: 73%;
  }
  [data-poll-bar-fill][data-percent="74"] {
    width: 74%;
  }
  [data-poll-bar-fill][data-percent="75"] {
    width: 75%;
  }
  [data-poll-bar-fill][data-percent="76"] {
    width: 76%;
  }
  [data-poll-bar-fill][data-percent="77"] {
    width: 77%;
  }
  [data-poll-bar-fill][data-percent="78"] {
    width: 78%;
  }
  [data-poll-bar-fill][data-percent="79"] {
    width: 79%;
  }
  [data-poll-bar-fill][data-percent="80"] {
    width: 80%;
  }
  [data-poll-bar-fill][data-percent="81"] {
    width: 81%;
  }
  [data-poll-bar-fill][data-percent="82"] {
    width: 82%;
  }
  [data-poll-bar-fill][data-percent="83"] {
    width: 83%;
  }
  [data-poll-bar-fill][data-percent="84"] {
    width: 84%;
  }
  [data-poll-bar-fill][data-percent="85"] {
    width: 85%;
  }
  [data-poll-bar-fill][data-percent="86"] {
    width: 86%;
  }
  [data-poll-bar-fill][data-percent="87"] {
    width: 87%;
  }
  [data-poll-bar-fill][data-percent="88"] {
    width: 88%;
  }
  [data-poll-bar-fill][data-percent="89"] {
    width: 89%;
  }
  [data-poll-bar-fill][data-percent="90"] {
    width: 90%;
  }
  [data-poll-bar-fill][data-percent="91"] {
    width: 91%;
  }
  [data-poll-bar-fill][data-percent="92"] {
    width: 92%;
  }
  [data-poll-bar-fill][data-percent="93"] {
    width: 93%;
  }
  [data-poll-bar-fill][data-percent="94"] {
    width: 94%;
  }
  [data-poll-bar-fill][data-percent="95"] {
    width: 95%;
  }
  [data-poll-bar-fill][data-percent="96"] {
    width: 96%;
  }
  [data-poll-bar-fill][data-percent="97"] {
    width: 97%;
  }
  [data-poll-bar-fill][data-percent="98"] {
    width: 98%;
  }
  [data-poll-bar-fill][data-percent="99"] {
    width: 99%;
  }
  [data-poll-bar-fill][data-percent="100"] {
    width: 100%;
  }

  [data-poll-suggest] {
    margin: 0;
  }

  [data-poll-suggest] > summary {
    /* Inherits [data-poll-option] from the markup, so it lines up with the real
   * choices. The default disclosure triangle is replaced by a "+" that reads
   * as "add" rather than "expand". */
    list-style: none;
    color: var(--noon-muted, #666);
  }

  [data-poll-suggest] > summary::-webkit-details-marker {
    display: none;
  }

  [data-poll-suggest] > summary::before {
    content: "+";
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* MATCHES THE CHECKBOX BESIDE IT, which the old rule only appeared to do.
   * Both said `1.1em`, but this element also carried `font-size: 0.9em`, and
   * `em` resolves against the element's OWN size — so the circle actually drew
   * at 0.99em against the checkboxes' 1.1em, with a 0.9em glyph inside it. It
   * read as a smaller, weaker control than the options it sits under.
   *
   * The glyph now inherits the row's size and gains weight instead. Sizing the
   * circle and its content off the SAME font size is what keeps the two columns
   * lined up when the theme's base size changes. */
    width: 1.1em;
    height: 1.1em;
    border: 1px solid var(--noon-border, #ddd);
    border-radius: 50%;
    font-weight: 600;
    line-height: 1;
  }

  [data-poll-suggest][open] > summary {
    color: inherit;
  }

  /* Hidden VISUALLY, still in the accessibility tree — the same technique the
 * legend uses above, and for the same reason. `display:none` here would leave
 * the input with no accessible name at all. */
  [data-poll-field-label] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  [data-poll-suggest] > label {
    display: flex;
    align-items: center;
    gap: calc(var(--noon-spacing-unit, 8px) * 1);
    /* Indented to the depth of an option's label, so the field belongs to the
   * row above it rather than floating loose in the fieldset. */
    padding: calc(var(--noon-spacing-unit, 8px) * 1) 0 0 1.6em;
  }

  [data-poll-suggest] input[type="text"] {
    flex: 1 1 12rem;
    padding: calc(var(--noon-spacing-unit, 8px) * 1);
    border: 1px solid var(--noon-border, #ddd);
    border-radius: var(--noon-radius, 4px);
  }

  /* The "Add" button is secondary to "Vote": same shape, no fill, so the primary
 * action on the form stays visually singular. */
  [data-poll-suggest] button {
    margin: calc(var(--noon-spacing-unit, 8px) * 1) 0 0 1.6em;
    background: transparent;
    color: inherit;
  }

  /* ── close of @layer noon ── */
}
