/* plan-locks.css — visual "locked / upgrade" state for plan-gated controls.
   Applied by /js/plan-locks.js to any [data-plan-feature] the account can't use. */

/* ── THE LOCK MARKER, DEFINED ONCE FOR BOTH TREATMENTS ───────────────────
   There are two places a padlock is drawn — .plan-locked::after (a control this
   file's JS or the server marked locked) and .plan-lock-icon (the server-rendered
   <x-plan-lock> badge on the template gallery). They read the SAME three tokens,
   so a change to the glyph, its size or its colour reaches both and the two
   cannot drift into different marks.

   THE TOKENS LIVE HERE, NOT IN tokens.css, because this is the only stylesheet
   both treatments load. (Until 2026-09-19 there was a second reason and it is gone:
   the template gallery, templates/index.blade.php, is a standalone page that did NOT
   link tokens.css, so a token defined there resolved to nothing on the one page the
   badge is for. It links tokens.css now — P9 step 1 — which is why every literal
   fallback this file carried "for the gallery" is gone below.)

   WHY A MASK AND NOT A background-image. The --icon-*-svg family in tokens.css
   bakes its colour in as a literal, because a data: URL cannot read a custom
   property — which is why --icon-embed-svg had to ship a second copy
   (--icon-embed-svg-light) to exist in white. A mask keeps the data-URI SVG
   convention for the SHAPE and lets background-color supply the ink, so the grey
   is the project's muted token itself rather than a hand-copied hex that a token
   edit would leave behind. Same asset convention, no second icon source.

   Size and gap come off the --space-* scale in tokens.css. THE LITERAL FALLBACKS
   ARE DELETED (2026-09-19): they existed only for the gallery page, which now links
   tokens.css, and a fallback that can no longer fire is a second statement of a value
   that reads as a live one. The size was --space-md (16px) and is one step up at
   --space-lg (24px); it is a token, so both treatments and the rail's greyed label
   move together. */
:root {
    --plan-lock-icon-size: var(--space-lg);
    --plan-lock-icon-gap:  var(--space-xs);
    --plan-lock-icon-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='4.6' y='8.9' width='10.8' height='8' rx='1.3' fill='none' stroke='%23000' stroke-width='1.4'/%3E%3Cpath d='M7.3 8.9 V6.7 a2.7 2.7 0 0 1 5.4 0 V8.9' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
}

.plan-locked {
    opacity: 0.55;
    cursor: not-allowed !important;
    /* keep pointer events so the capture-phase guard can intercept + prompt */
    pointer-events: auto;
}

/* THE GAP IS THE HOST'S, AND THERE IS ONLY ONE OF IT.
   The marker used to carry margin-left:6px of its own. On a flex host that
   double-counted: .tpl-pill-toggle is inline-flex with gap:8px — a gap sized for
   a toggle followed by its text label — and a locked rail toggle holds no text,
   so the 8px was spacing the padlock as though it were one. Measured on the
   setup page: the 72px track ended at x=118 and the label box at x=137, 19px of
   separation for a 4.6px glyph.

   So the lock hosts are normalised to ONE layout here rather than the marker
   being pulled back toward the control: every locked control that can carry the
   marker becomes a centred inline-flex row whose column-gap IS the spacing. That
   also gives the inline-block hosts (.tpl-action-btn — the export buttons, the
   viewer-link create button, the docs upload label) the same gap, which a
   margin-on-the-marker could only approximate. Inputs are excluded: ::after does
   not render on a replaced element, so they have no marker to space (they take
   the grayscale arm below), and forcing a display on them is a change with no
   subject. LAYOUT ONLY in this block, deliberately — see
   .claude/rules/css-specificity.md on splitting layout from type. */
.plan-locked:not(input) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    column-gap: var(--plan-lock-icon-gap);
}

.plan-locked::after {
    content: "";
    flex: none;
    width: var(--plan-lock-icon-size);
    height: var(--plan-lock-icon-size);
    background-color: var(--muted);
    -webkit-mask-image: var(--plan-lock-icon-svg);
    mask-image: var(--plan-lock-icon-svg);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

/* Locked form controls (toggles/checkboxes) can't take ::after — dim them. */
input.plan-locked,
button.plan-locked {
    filter: grayscale(1);
}

/* ── THE SERVER-RENDERED PADLOCK (resources/views/components/plan-lock.blade.php)
   A per-MEMBER lock on a set key, decided on the server. Nothing above applies to
   it: .plan-locked is what plan-locks.js puts on a control it found, and that
   mechanism is per-key and needs window.planFeatures, which a public page does
   not emit. These classes are rendered already locked, so they carry no state and
   no JS reads them. */

.plan-lock {
    display: inline-flex;
    align-items: center;
    gap: var(--plan-lock-icon-gap);
    font-family: var(--font-body);
    /* P6c held this at a 12px literal and P6d held the tracking at 0.08em, both with
       the same note: <x-plan-lock>'s only consumer is the template gallery, which did
       not load tokens.css, so a var() here went invalid and the badge inherited its
       ancestor's size (measured 12px -> 10px on computed-style-dump.py's
       templates-index-1280 cell). The gallery links tokens.css as of P9 step 1, so
       both read the tier. Computed value unchanged: 12px, 0.96px tracking. */
    font-size: var(--type-caption);
    letter-spacing: var(--type-caption-tracking-wide);
    text-transform: uppercase;
    padding: 5px 10px;
    border: 1px solid rgba(var(--ink-rgb), 0.18);
    color: var(--muted);
    background: rgba(26, 18, 8, 0.04);
    white-space: nowrap;
}

/* The badge's glyph — the SAME mark as .plan-locked::after above, off the same
   three tokens, so the gallery's padlock and a locked control's padlock are one
   icon at one size in one grey.

   --muted's literal fallback is GONE (P9-leftovers item 2, D-DEBT-99 item 13):
   tokens.css now declares --muted itself, so every var() in this file resolves
   out of tokens.css, which reaches all four pages that load this sheet. The
   three fallbacks read `var(--muted, #8C8078)` until this change — carried
   because the name had no single home, not because a page was missing the
   sheet (blocks.css and templates/index.blade.php's own :root both already
   declared the same alias, so the fallback never actually fired). */
.plan-lock-icon {
    display: inline-block;
    flex: none;
    width: var(--plan-lock-icon-size);
    height: var(--plan-lock-icon-size);
    background-color: var(--muted);
    -webkit-mask-image: var(--plan-lock-icon-svg);
    mask-image: var(--plan-lock-icon-svg);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

/* The badge's own text is the plan name; the sentence is for a screen reader. */
.plan-lock-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* A whole card/row the account cannot open. Greyed, NOT hidden: a filtered list
   leaks the moment one list forgets to filter, and a lock the reader can see is
   the only version that sells anything. */
.plan-lock-subject {
    opacity: 0.62;
}

/* ── THE POPOVER A LOCKED CONTROL OPENS (public/js/plan-locks.js) ────────
   Built by openPrompt(), which is the implementation of the
   window.showUpgradePrompt hook that existed for months with nothing behind it —
   so every lock on the platform fell through to window.alert().

   IT IS NO LONGER A MODAL. The panel used to be a centred box on a dimmed
   full-screen backdrop (.plan-lock-prompt was position:fixed;inset:0 with a
   .plan-lock-prompt-panel inside it, both DELETED here). It is now the panel
   itself, placed beside the control that was clicked by
   window.tplMenuOverlay.anchor — the template switcher's positioner, which
   flips above the anchor when there is no room below and clamps to the viewport.
   Nothing here positions it: no top/left/inset, because the JS owns those and a
   competing value in the stylesheet is how two positioners start disagreeing.
   Neutral chrome, deliberately: it is an invitation, not an error. */

.plan-lock-prompt {
    position: fixed;                 /* the anchor sets top/left; see above */
    z-index: 10000;
    width: max-content;
    max-width: 280px;
    padding: var(--inset-panel) 16px 12px;
    background: var(--surface-raised);
    border: 1px solid rgba(var(--ink-rgb), 0.18);
    box-shadow: 0 10px 28px rgba(26, 18, 8, 0.18);
}

/* Fallback only — the anchoring module was not on the page, so there is no
   element to hang off. Centre it rather than leaving it at 0,0. */
.plan-lock-prompt--centred {
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.plan-lock-prompt-body {
    margin: 0 0 var(--inset-panel);
    font-family: var(--font-body);
    font-size: var(--type-label);
    line-height: 1.45;
    text-align: center;
    color: var(--ink, #1A1208);
}

/* THE PAIR IS TWO EQUAL TRACKS, not two shrink-to-fit buttons that happen to
   look even. "Unlock feature" and "Close" are different lengths, so a flex row
   sized them differently and right-aligned the result; a grid of two 1fr tracks
   makes them the same width by construction at any label length, and the grid
   itself is centred in the box. No fixed pixel width on either button. */
.plan-lock-prompt-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--inset-control);
}

.plan-lock-prompt-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--inset-control) var(--inset-box);
    font-family: var(--font-body);
    font-size: var(--type-caption);
    letter-spacing:var(--type-caption-tracking-wide);
    text-transform: uppercase;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    color: var(--ink, #1A1208);
    background: transparent;
    border: 1px solid rgba(var(--ink-rgb), 0.18);
}

/* The lead button is the platform's success green — --success, which is
   var(--green) and the same token the session-title completion check paints its
   disc with (--quiz-correct resolves to the identical value). No new hex. */
.plan-lock-prompt-btn--lead {
    color: var(--color-white, #fff);
    background: var(--success, #7ab648);
    border-color: var(--success, #7ab648);
}
