/* The store page.
 *
 * The gold "uncurse my dice" banner that used to sit at the foot of the roller
 * pane is gone — replaced by the entropy control in the roller's own footer
 * row. Its rules went with it on 2026-08-09. `.qb-mark` and `.qb-buy` are all
 * that remain of the prefix, and both are still worn by unlock.html.
 *
 * Colours come from the theme files, so the page follows the site's schemes and
 * day/night mode. The one deliberate departure is the gold accent, kept from
 * Tia's original badge — it reads as "premium" against a site that is
 * otherwise red, and it is the only place on the site that colour appears. */

:root {
    --store-gold: #c9a227;
    --store-gold-edge: rgba(201, 162, 39, 0.6);
    --store-black: #12100e;
    --store-black-hover: #1b1815;
}

.qb-mark { color: var(--text-primary); }

/* The product name, not a section heading - it is what the page is selling and
   the first thing worth reading. Left in the body serif rather than the celtic
   display face, which is spoken for by the "Store" page title directly above:
   two display headings stacked read as two page titles. */
.store-title {
    /* Scales with the viewport so it stays on one line on a phone. "True
       Randomness" broken across two lines reads as two things, not one product
       name, and the diamond ends up orphaned above the words. */
    font-size: clamp(1.4rem, 6.4vw, 2em);
    font-weight: 700;
    line-height: 1.2;
    text-align: center;
    margin: 0 0 4px;
}

/* Also worn by the signed-out sign-in link, so it has to behave as a button
   whether it is a <button> or an <a>: an anchor otherwise arrives underlined
   and in the browser's own link colour. */
.qb-buy {
    display: inline-block;
    background-color: var(--store-black);
    color: var(--store-gold);
    border: 1px solid var(--store-gold);
    border-radius: 999px;
    padding: 9px 18px;
    font-weight: 700;
    font-size: 0.9em;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
}

a.qb-buy:link,
a.qb-buy:visited,
a.qb-buy:hover {
    color: var(--store-gold);
    text-decoration: none;
}

.qb-buy:hover:not(:disabled) { background-color: var(--store-black-hover); }
.qb-buy:disabled { opacity: 0.6; cursor: default; }

/* ── The store page ──────────────────────────────────────────────── */

.store-content { max-width: 640px; }

.store-price {
    color: var(--text-primary);
    font-size: 1.5em;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    /* Centred to sit with .store-title as one block. Left-aligned under a
       centred title, it read as the first line of the body copy. */
    text-align: center;
}

.store-owned {
    display: inline-block;
    border: 2px solid var(--ok);
    color: var(--ok);
    background-color: var(--bg-secondary);
    border-radius: 999px;
    padding: 5px 14px;
    font-weight: 700;
    font-size: 0.85em;
}

.store-points {
    margin: 0;
    padding-left: 18px;
    font-size: 0.92em;
    color: var(--text-primary);

    /* Armour. Keeps its bullets — `disc` is the browser default it shows now. */
    list-style: disc;
    padding-top: 0;
    padding-right: 0;
    padding-bottom: 0;
    line-height: 1;
}

.store-points li {
    margin: 0 0 6px;
    list-style: disc;
    padding: 0;
    font-size: 1em;
    text-indent: 0;
    letter-spacing: normal;
    color: inherit;
    font-family: inherit;
    text-transform: inherit;
}

.store-fineprint {
    color: var(--text-primary);
    font-size: 0.8em;
    font-style: italic;
}

/* ── The entropy control on the roller ───────────────────────────
   Two parts. The outer element is an invisible column exactly as wide as a
   dice line, sitting in the same place: .button-group hangs outside each line
   at left:-28px, so .d-line is the first in-flow child and starts at x=0, and
   so does this. The pill inside is sized to its own text and centred within
   that column — so its midpoint is the midpoint of the input boxes above it,
   not of the whole row.

   The top offset centres it on ALL, which is 54px tall at top:7px and so
   overhangs this row. */
.entropy-status {
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 0 0 auto;
    min-width: 180px;
    max-width: 190px;
    width: 190px;
    /* Empty until entropy.js has asked the server what the account owns, which
       is a round trip that lands after the page has painted. Every state wears
       the same pill, so the row can hold its height from the start and the
       roll log below it stops jumping. 31px is that pill measured: the 27px
       height below plus its 2px border top and bottom, which is outside the
       height because nothing here sets box-sizing. */
    min-height: 31px;
    margin: 20px 0 0 0;
}

/* Tia's pill, kept close to how she wrote it — dark ground, gold rule,
   monospace, fully rounded — but 2px to match the roller's own controls, and
   in the row rather than floating over the page where it covered the roll
   buttons on a phone. */
.entropy-status a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    max-width: 100%;
    height: 27px;
    padding: 0 15px;
    font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    background: var(--store-black);
    color: var(--store-gold);
    border: 2px solid var(--store-gold-edge);
    border-radius: 999px;
    box-shadow: 0 2px 14px rgba(0, 0, 0, 0.3);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.entropy-status a:hover { background: var(--store-black-hover); }

/* Every state wears the same pill. This used to be muted to transparent with a
   grey border so that rolling locally would "recede", but on parchment that
   read as a broken or disabled control rather than a quieter one, and its
   white hover made it look like something had gone wrong when you moused over
   it. The distinction between the states is carried by the wording and the
   ◇/◆ marker, which is enough: this is a label telling you where your numbers
   came from, and all three answers deserve the same confidence. */

@media screen and (max-width: 640px) {
    .entropy-status a { font-size: 12px; padding: 0 12px; }
}

/* The notes under the button inherit the browser's link colour otherwise,
   which lands as blue-on-parchment next to a gold-and-red page. */
.setting-note a,
.store-fineprint a {
    color: var(--theme-primary);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Payment terms. Upright rather than italic so it reads as terms and not as a
   third aside, and sat directly under the button where it is seen before
   paying rather than buried at the bottom of the page. */
.store-terms {
    margin: 18px 0 0;
    font-size: 0.82em;
    line-height: 1.55;
    color: var(--text-primary);
}

/* ── The pulse receipt at the foot of a log entry ──────────────────────────
 *
 * Every roll under nist-beacon carries the pulse it drew on, so an individual
 * result in the log can be taken back to the signed public record it came
 * from. That is the whole product: not "this is random, trust us", but a
 * number you can check against NIST yourself, months later.
 *
 * Written by beaconReceipt() in dnddiceroller.js, and only under nist-beacon
 * — under secure-enclave there is no pulse and nothing is emitted.
 *
 * Deliberately quieter than the status pill above the roller. That one is a
 * control and wants to be found; this repeats on every entry in a log that
 * can run to hundreds of lines, and shouting it would drown the dice. Same
 * gold, same monospace, no pill, small.
 */
.log-beacon {
    margin: 4px 0 2px;
    font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: .02em;
    line-height: 1.5;
}

.log-beacon a {
    /* Theme-aware: see --log-beacon in the theme files. The log panel is light in
       day mode and dark at night, so a fixed colour cannot be right in both. */
    color: var(--log-beacon);
    text-decoration: none;
    border-bottom: 1px solid currentColor;
    opacity: .92;
}

/* The log sits on a dark panel, so :visited must be pinned. Left alone it goes
   browser-purple, and after a few rolls the log turns into a wall of purple —
   which also, wrongly, makes an unclicked pulse look different from a clicked
   one when they are equally verifiable. */
.log-beacon a:visited { color: var(--log-beacon); }

.log-beacon a:hover,
.log-beacon a:focus {
    color: var(--log-beacon-hover);
    border-bottom-color: currentColor;
    opacity: 1;
}

/* The device fallback. No link, because there is no pulse to link to: the
   beacon could not be reached and the roll happened locally. Muted rather
   than red — it is not an error, it is the honest fallback working, and the
   roll it describes is still a perfectly good roll. */
.log-beacon-device {
    color: var(--text-secondary);
    opacity: .85;
}

.log-beacon-sep {
    color: var(--text-secondary);
    opacity: .6;
    margin: 0 2px;
}

@media screen and (max-width: 640px) {
    .log-beacon { font-size: 10px; }
}

/* The hash and the certificate link sit after the pulse on the same receipt
   line. The hash is data, not a control, so it is muted; the certificate is a
   link like the pulse and shares its colour. */
.log-beacon-hash {
    color: var(--text-secondary);
    opacity: .85;
    letter-spacing: 0;
}
