/* Checkout-only styles.
   Ported from the Lovable rebuild of this page: tab panels become bordered
   cards, plan and billing choices become selectable tiles with visible radios,
   and the licence code lands in an accent panel rather than a bare textarea.
   Everything reads from the shared tokens in style.css, so both themes and
   the secondary hues stay in step. */

/* --- tabs --- */
.tabs {
    display: flex; gap: 4px; flex-wrap: wrap;
    border-bottom: 1px solid var(--rule); margin-bottom: 26px;
}
.tab {
    appearance: none; background: none; border: 0;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
    border-radius: var(--radius) var(--radius) 0 0;
    font: inherit; font-weight: 600; font-size: .95rem; color: var(--ink-muted);
    padding: 12px 16px; cursor: pointer; transition: color .15s, border-color .15s;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--accent-text); border-bottom-color: var(--accent); }
.tabpanel[hidden] { display: none; }

/* --- panels --- */
.card-panel {
    background: var(--surface); border: 1px solid var(--rule);
    border-radius: 16px; padding: clamp(22px, 4vw, 34px);
}
.card-panel h2 { font-size: 1.05rem; font-weight: 700; }
.panel-lede { font-size: .94rem; color: var(--ink-muted); margin-top: 8px; }
.card-panel > .panel-lede:first-child { margin-top: 0; }
/* A panel that explains rather than asks -- "Moving to a new PC" -- runs to a
   second paragraph, and the reset leaves consecutive ones touching. */
.card-panel p + p { margin-top: 10px; }

/* Retrieve and transfer are two separate jobs, so they get a card each rather
   than one long column split by a rule. */
.panel-grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* --- forms --- */
.form { display: grid; gap: 24px; margin-top: 22px; }
.card-panel > .form:first-child { margin-top: 0; }

.field { display: grid; gap: 8px; }
.field label {
    font-family: var(--font-mono); font-size: .72rem; font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted);
}
.field .hint { font-size: .82rem; color: var(--ink-muted); }
/* Marks a field the buyer can skip without losing anything. The label stays
   the label; this rides alongside it rather than bracketed into the text. */
.field .optional {
    margin-left: 6px; font-weight: 400; letter-spacing: .1em;
    text-transform: uppercase; opacity: .65;
}
input:not([type="radio"]) {
    font: inherit; font-size: .95rem; width: 100%;
    padding: 11px 13px; border-radius: var(--radius);
    border: 1px solid var(--rule); background: var(--surface); color: var(--ink);
}
input.mono { font-family: var(--font-mono); font-size: .88rem; }
input::placeholder { color: var(--ink-muted); opacity: .7; }

/* --- plan and billing tiles --- */
.choice { border: 0; margin: 0; padding: 0; min-width: 0; }
.choice legend {
    padding: 0; margin-bottom: 12px;
    font-family: var(--font-mono); font-size: .72rem; font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted);
}
.choice-row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
/* The radio stays visible rather than being swapped for a highlighted tile:
   with it hidden the options read as buttons, and which one was already
   chosen was never obvious. It is positioned over the tile's left gutter so
   the sibling selector below can still style the tile from its checked state. */
.opt { display: block; cursor: pointer; position: relative; }
.opt > input {
    position: absolute; top: 18px; left: 17px; z-index: 1;
    width: auto; margin: 0; accent-color: var(--accent);
}
.opt > span {
    display: grid; gap: 3px; align-content: start; height: 100%;
    border: 1px solid var(--rule); border-radius: var(--radius);
    padding: 15px 16px 15px 44px; background: var(--surface);
    transition: border-color .15s, background .15s;
}
.opt:hover > span { border-color: var(--ink-muted); }
.opt > input:checked + span { border-color: var(--accent); background: var(--accent-soft); }
.opt > input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.opt b { font-size: .95rem; font-weight: 700; }
.opt .opt-price { font-size: .95rem; font-variant-numeric: tabular-nums; }
.opt small {
    font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-muted);
}
.opt .opt-note { font-size: .82rem; line-height: 1.5; color: var(--ink-muted); }

/* --- school total --- */
.total {
    border: 1px solid var(--rule); border-radius: var(--radius);
    background: var(--accent-soft); padding: 18px 20px;
}
.total-amount {
    margin-top: 6px; font-size: 1.75rem; font-weight: 800;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--accent-text);
}
.total-note { margin-top: 4px; font-size: .84rem; color: var(--ink-muted); }

.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }

/* --- notices --- */
.notice {
    /* Top-aligned, not centred: once the message runs to two or three lines on
       a phone, a centred spinner sits against the middle line and reads as
       unrelated to the sentence it belongs to. */
    display: flex; align-items: flex-start; gap: 10px; max-width: none;
    flex-wrap: wrap;
    margin-bottom: 20px; padding: 13px 16px;
    border: 1px solid var(--rule); border-radius: var(--radius);
    font-size: .9rem; color: var(--ink-muted);
}
.notice[hidden] { display: none; }
#notice-error { border-color: #b91c1c; color: #b91c1c; }
:root[data-theme="dark"] #notice-error { border-color: #fca5a5; color: #fca5a5; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) #notice-error { border-color: #fca5a5; color: #fca5a5; }
}

/* Without a zero basis the message is laid out at its max-content width, does
   not fit beside the spinner, and wraps to a line of its own -- leaving the
   spinner orphaned above it. Zero basis lets it shrink and wrap internally
   instead, so all three stay on one row. */
#notice-wait-text { flex: 1 1 0; min-width: 0; }

/* Sits at the far end of the wait notice. It only stops us looking for the
   code -- it cannot call a payment back -- so it is quiet, not a button. */
.notice-stop {
    margin-left: auto; flex: none; padding: 0; border: 0; background: none;
    font: inherit; color: inherit; cursor: pointer;
    text-decoration: underline; text-underline-offset: 3px;
}
.notice-stop:hover { color: var(--ink); }
.notice-stop[hidden] { display: none; }

.spinner {
    /* Nudged down onto the optical centre of the first line of text. */
    width: 15px; height: 15px; flex: none; margin-top: 4px; border-radius: 50%;
    border: 2px solid var(--rule); border-top-color: var(--accent);
    animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }

/* --- the code --- */
.code-box {
    margin-top: 24px; padding: clamp(20px, 3vw, 26px);
    border: 1px solid var(--accent); border-radius: 14px; background: var(--accent-soft);
}
.code-box[hidden] { display: none; }
/* What was bought, under the "it is on its way" line. A receipt, not a code:
   the code only ever exists in the email. */
.receipt { margin: 16px 0 4px; display: grid; gap: 6px; }
/* The same trap as .btn in style.css: this grid would otherwise ignore the
   hidden attribute. On /checkout a receipt only ever hides inside .code-box,
   which hides itself; /authorise hides one on its own. */
.receipt[hidden] { display: none; }
.receipt > div { display: flex; justify-content: space-between; gap: 16px;
    padding-bottom: 6px; border-bottom: 1px solid var(--rule); }
.receipt dt { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-muted); }
.receipt dd { font-size: .94rem; text-align: right; word-break: break-word; }
#sent-to { word-break: break-all; }
.code-hint { margin-top: 14px; font-size: .88rem; }

/* --- phones ---
   Three tab labels do not fit on one line at 390px, and wrapping them left a
   rule running through the middle of the group. They scroll instead, the same
   way the header's nav links do. */
@media (max-width: 560px) {
    .tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    .tabs::-webkit-scrollbar { display: none; }
    .tab { white-space: nowrap; padding-inline: 12px; }
    .tab:first-child { padding-left: 0; }
    .actions .btn { width: 100%; }
    /* Sharing the row with the message leaves it about twenty characters
       wide, which turns three lines into five. Give the message the full
       width and put the control underneath. */
    .notice-stop { flex-basis: 100%; text-align: right; }
}

/* DPDP consent — the checkbox that must be ticked before payment.
   Unchecked by default, never pre-ticked. The forms carry novalidate, so
   the gate is enforced in checkout.js as well as here. */
.consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 18px 0 6px;
  font-size: .92rem;
  line-height: 1.55;
  color: var(--ink-muted);
}
.consent input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 2px 0 0;
  accent-color: var(--accent);
}
.consent a { color: var(--accent-text); text-decoration: underline; }
