
:root { color-scheme: light; --brand-bg: #ffffff; --brand-text: #202020; --brand-heading: #202020; --brand-muted: #666666; --brand-subtle: #737373; --brand-link: #202020; --brand-focus: #05163d; --brand-divider: #ededed; --brand-outline: #dedede; --brand-surface: #f6f6f6; --brand-hover: #f7f7f7; --brand-danger: #a32929; --brand-success: #286548; --brand-font: "Arial", "Helvetica", sans-serif; --brand-font-size: 14px; --brand-line-height: 1.6; --brand-heading-font: "Arial", "Helvetica", sans-serif; --brand-heading-size: 30px; --brand-heading-weight: 500; --brand-heading-tracking: -0.6px; --brand-mono: ui-monospace, "Menlo", "Consolas", monospace; --brand-button-height: 48px; --brand-button-radius: 28px; --brand-button-weight: 400; --brand-button-bg: #ffffff; --brand-button-text: #202020; --brand-button-border: #d9d9d9; --brand-button-hover: #f7f7f7; --brand-primary-bg: #242424; --brand-primary-text: #ffffff; --brand-primary-border: #242424; --brand-primary-hover: #363636; --brand-input-height: 50px; --brand-input-radius: 28px; --brand-input-bg: #ffffff; --brand-input-text: #202020; --brand-input-border: #dedede; --brand-input-focus: #4f7df3; --brand-input-disabled-bg: #f7f7f7; --brand-input-disabled-text: #888888; --brand-box-radius: 12px; --brand-card-bg: #edf2f7; --brand-card-bg-end: #dce5ee; --brand-card-border: #e1e5e9; --brand-card-text: #172537; --brand-card-radius: 14px; --brand-logo-width: 136px; --brand-logo-opacity: 0.8; }
* { box-sizing: border-box; }
body { margin: 0; background-color: var(--brand-bg); color: var(--brand-text); font-family: var(--brand-font); font-size: var(--brand-font-size); line-height: var(--brand-line-height); -webkit-font-smoothing: antialiased; }
button, input { font: inherit; font-size: 16px; }
button:focus-visible, a:focus-visible, summary:focus-visible { outline: 2px solid var(--brand-focus); outline-offset: 3px; }
/* A field in use: its own border turns blue, as on ChatGPT's sign-in, rather than a ring around it. */
input:focus, input:focus-visible { outline: none; border-color: var(--brand-input-focus); box-shadow: 0 0 0 1px var(--brand-input-focus); }
a { color: inherit; }
/*
 * The card centred in the window, at any height: the logo in the first row, the card in the second, and the first and
 * last rows sharing what space is left equally. A card taller than the window runs on from under the logo instead.
 */
.auth-layout { min-height: 100dvh; display: grid; grid-template-rows: 1fr auto 1fr; }
.auth-brand { padding: 28px; align-self: start; }
.auth-brand a { display: inline-block; }
.auth-brand img { width: var(--brand-logo-width); height: auto; opacity: var(--brand-logo-opacity); display: block; }
.auth-page-card { grid-row: 2; width: min(360px, calc(100vw - 40px)); margin: 36px auto; text-align: center; }
.auth-page-card.wide { width: min(480px, calc(100vw - 40px)); text-align: left; }
h1 { font-family: var(--brand-heading-font); font-size: var(--brand-heading-size); line-height: 1.25; font-weight: var(--brand-heading-weight); letter-spacing: var(--brand-heading-tracking); color: var(--brand-heading); margin: 8px 0 14px; }
.wide h1 { font-size: 26px; }
h2 { font-family: var(--brand-heading-font); font-size: 16px; font-weight: 500; color: var(--brand-heading); margin: 28px 0 8px; }
.lead, .auth-description { color: var(--brand-muted); line-height: 1.65; font-size: 14px; margin: 16px 0 24px; overflow-wrap: anywhere; }
.small { font-size: 12px; color: var(--brand-subtle); line-height: 1.5; }
button, a.button { width: 100%; min-height: var(--brand-button-height); border: 1px solid var(--brand-button-border); border-radius: var(--brand-button-radius); display: flex; align-items: center; justify-content: center; gap: 10px; background: var(--brand-button-bg); color: var(--brand-button-text); font-weight: var(--brand-button-weight); margin: 12px 0 0; padding: 0 18px; cursor: pointer; text-decoration: none; text-align: center; }
button:hover, a.button:hover { background: var(--brand-button-hover); }
button.primary, a.button.primary { background: var(--brand-primary-bg); color: var(--brand-primary-text); border-color: var(--brand-primary-border); }
button.primary:hover, a.button.primary:hover { background: var(--brand-primary-hover); }
button:disabled { cursor: default; opacity: .45; }
/* A button at work (loadingDots in the script): the custodial web app's three dots (its TypingDots), in the button's colour, in place of its words. */
button[aria-busy="true"]:disabled { opacity: 1; }
.loading-dots { display: inline-flex; align-items: center; gap: 4px; height: 14px; vertical-align: middle; }
.loading-dots > span { width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .5; }
@keyframes loading-dot { 0%, 60%, 100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-4px); opacity: .95; } }
@media (prefers-reduced-motion: no-preference) {
  .loading-dots > span { animation: loading-dot 1.2s ease-in-out infinite; }
  .loading-dots > span:nth-child(2) { animation-delay: .15s; }
  .loading-dots > span:nth-child(3) { animation-delay: .3s; }
}
/* Some browsers send no pointer events from a disabled control, so a pointer resting on a held button would never
   show the page it is seen: the page beneath it takes them instead, which is what arms the button. */
button.guarded:disabled { pointer-events: none; }
button svg, a.button svg { width: 18px; height: 18px; flex-shrink: 0; }
label { display: block; text-align: left; margin: 16px 0 6px; font-size: 12px; color: var(--brand-muted); }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
input { width: 100%; height: var(--brand-input-height); border: 1px solid var(--brand-input-border); border-radius: var(--brand-input-radius); padding: 0 18px; background: var(--brand-input-bg); color: var(--brand-input-text); }
input:disabled { background: var(--brand-input-disabled-bg); color: var(--brand-input-disabled-text); }
.notice, .auth-notice { padding: 14px; background: var(--brand-surface); border-radius: var(--brand-box-radius); color: var(--brand-muted); font-size: 13px; line-height: 1.6; margin: 20px 0; text-align: left; }
/* Between a step's own button and the other way in. */
.or { margin: 14px 0 2px; font-size: 13px; color: var(--brand-muted); }
.switch { margin-top: 28px; font-size: 14px; color: var(--brand-muted); }
.switch a { color: var(--brand-link); text-decoration: underline; text-underline-offset: 2px; }
/* A text button (pages.ts textButton): an action in words, not underlined, such as "Resend code". */
button.text-button { display: inline; width: auto; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; color: var(--brand-link); font-size: 14px; font-weight: 400; text-decoration: none; }
button.text-button:hover { background: none; }
/* Where the code went, as plain text. */
#code-sent { overflow-wrap: anywhere; }
.auth-legal { display: flex; justify-content: center; gap: 12px; margin-top: 48px; font-size: 13px; color: var(--brand-muted); }
.auth-legal a { text-decoration: underline; text-underline-offset: 2px; }
.actions { display: grid; gap: 0; margin-top: 12px; }
/* A display rule would otherwise show what the script hid (the decision buttons once decided). */
[hidden] { display: none !important; }
ul.lines { padding-left: 1.2rem; margin: 8px 0 16px; }
ul.lines li { margin: 6px 0; }
ul.ways-in, ul.websites { list-style: none; padding: 0; margin: 0; }
ul.ways-in li { display: flex; justify-content: space-between; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--brand-divider); }
ul.websites li { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--brand-divider); }
ul.websites li span { display: block; }
ul.websites button, ul.websites a.button { width: auto; min-height: 36px; margin: 0; padding: 0 14px; font-size: 14px; }
ul.websites .row-actions { display: flex; gap: 8px; }
/* An address to open on another device: whole on one tap (user-select: all), so it copies in one piece. */
.address { font-family: var(--brand-mono); font-size: 13px; padding: 12px 14px; border: 1px solid var(--brand-outline); border-radius: var(--brand-box-radius); margin: 8px 0; overflow-wrap: anywhere; user-select: all; -webkit-user-select: all; }
/* The code a person compares with the one their device shows: large, spaced, never broken mid-group. */
.fingerprint { font-family: var(--brand-mono); font-size: 22px; letter-spacing: 1px; line-height: 1.5; padding: 14px; border: 1px solid var(--brand-outline); border-radius: var(--brand-box-radius); text-align: center; margin: 8px 0; overflow-wrap: anywhere; }
details.add-email { margin-top: 16px; }
details.add-email summary { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
dl { display: grid; grid-template-columns: max-content 1fr; gap: 8px 16px; margin: 16px 0; }
dt { color: var(--brand-muted); }
dd { margin: 0; overflow-wrap: anywhere; }
.card { border: 1px solid var(--brand-card-border); border-radius: var(--brand-card-radius); padding: 12px 14px; margin: 8px 0; overflow-wrap: anywhere; background: linear-gradient(135deg, var(--brand-card-bg), var(--brand-card-bg-end)); color: var(--brand-card-text); }
/* A recovery code, shown once: large, whole on one tap so it copies in one piece. */
.recovery-code { font-family: var(--brand-mono); font-size: 20px; letter-spacing: 1px; line-height: 1.6; padding: 14px; border: 1px solid var(--brand-outline); border-radius: var(--brand-box-radius); text-align: center; margin: 16px 0 8px; overflow-wrap: anywhere; user-select: all; -webkit-user-select: all; }
ul.notices { list-style: none; padding: 0; margin: 0; }
ul.notices li { padding: 10px 0; border-bottom: 1px solid var(--brand-divider); font-size: 13px; line-height: 1.5; }
#lost-passkey-link { color: var(--brand-muted); }
.rename { display: flex; gap: 8px; margin-top: 8px; }
.rename input { height: 40px; }
.rename .field { flex: 1; }
.rename button { width: auto; min-height: 40px; margin: 0; }
button.danger { color: var(--brand-danger); border-color: var(--brand-danger); }
/*
 * The account page (pages.ts accountPage): a header with the person's name and address, then its sections as cards (panel)
 * under small group labels, each card's heading with a line under it and its one action beside it. Every colour is
 * a brand token, so a website's look carries through.
 */
body[data-page="account"] .auth-page-card, body[data-page^="account-"] .auth-page-card { width: min(640px, calc(100vw - 32px)); }
/* The account page's links to its other pages, and their way back to it. */
.panel.link-list { padding: 4px 22px; }
a.link-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 0; border-top: 1px solid var(--brand-divider); text-decoration: none; }
a.link-row:first-child { border-top: 0; }
a.link-row strong { display: block; color: var(--brand-heading); font-size: 15px; font-weight: 600; }
a.link-row .small { display: block; margin-top: 2px; }
a.link-row .chevron { color: var(--brand-subtle); font-size: 22px; line-height: 1; }
a.link-row:hover strong { color: var(--brand-link); }
a.back-link { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 16px; color: var(--brand-link); font-size: 14px; text-decoration: none; }
.account-head { margin-bottom: 8px; }
.account-head h1 { margin: 0; font-size: 26px; overflow-wrap: anywhere; }
.account-sub { margin: 4px 0 0; color: var(--brand-muted); font-size: 14px; overflow-wrap: anywhere; }
.group-label { margin: 36px 0 10px; font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-subtle); }
.group-note { margin: 2px 4px 14px; }
.panel { border: 1px solid var(--brand-outline); border-radius: var(--brand-card-radius); background: var(--brand-bg); padding: 20px 22px; margin: 0 0 12px; }
.panel-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 12px 16px; }
.panel-title { flex: 1 1 220px; min-width: 0; }
.panel h2 { margin: 0; font-size: 17px; font-weight: 600; }
.panel-sub { margin: 4px 0 0; color: var(--brand-muted); font-size: 13px; line-height: 1.5; }
.panel-action { flex: none; }
.panel-action .button, .panel-action button, .panel-actions .button, .panel-actions button { width: auto; min-height: 36px; margin: 0; padding: 0 16px; font-size: 14px; white-space: nowrap; }
.panel-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.panel-note { margin: 14px 0 0; font-size: 12px; color: var(--brand-subtle); line-height: 1.5; }
.panel .empty { margin: 16px 0 0; color: var(--brand-muted); font-size: 14px; }
/* A card with no heading (the account's websites, devices and changes pages) starts with what it lists. */
.panel > .empty:first-child, .panel > ul:first-child { margin-top: 0; }
.account-head + .panel { margin-top: 20px; }
.panel ul.websites, .panel ul.notices { margin-top: 12px; }
.panel ul.websites li, .panel ul.notices li { border-bottom: 0; border-top: 1px solid var(--brand-divider); }
.panel ul.websites li:first-child, .panel ul.notices li:first-child { border-top: 0; }
#recovery-code-state { margin: 16px 0 0; font-size: 14px; }
.panel .add-email { margin-top: 12px; padding-top: 14px; border-top: 1px solid var(--brand-divider); }
.panel .add-email-open { margin: 0; }
.panel #add-email-form .lead { margin: 0 0 16px; }
.panel #add-email-form .switch { margin-top: 16px; text-align: center; }
.panel.danger { border-color: color-mix(in srgb, var(--brand-danger) 45%, var(--brand-outline)); }
.panel.danger h2 { color: var(--brand-danger); }
.panel.danger label { display: block; margin: 16px 0 8px; font-size: 13px; color: var(--brand-muted); }
.panel.danger button.danger { width: auto; min-height: 40px; margin-top: 12px; padding: 0 18px; font-size: 14px; }
@media (max-width: 480px) { .panel { padding: 16px; } .account-head h1 { font-size: 22px; } .group-label { margin-top: 28px; } }
#message { min-height: 24px; color: var(--brand-danger); font-size: 13px; margin: 16px 0 0; }
/* Under the field it is about: close to it, aligned with the field's text. */
#message.beside-field { min-height: 0; margin: 6px 0 0; padding: 0 18px; text-align: left; line-height: 1.5; }
input.invalid, input.invalid:focus, input.invalid:focus-visible { border-color: var(--brand-danger); box-shadow: 0 0 0 1px var(--brand-danger); }
/*
 * A field's placeholder, as the script lays it (floatingLabels): inside the field while it is empty and not in use,
 * and up in its top border, small, once it is in focus or holds text. The input's own placeholder is a space, kept
 * only so :placeholder-shown says whether it is empty. Raised, the label sits in a gap cut out of the border (a mask
 * as wide as the label, --notch, which the script measures), so whatever is behind the field shows through, a
 * website's background image included. The mask hides anything outside the input's box, so a field's focus and
 * error rings are drawn inside its border instead.
 */
.field { position: relative; }
.field input::placeholder { color: transparent; }
.field-label { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); padding: 0 4px; font-size: 16px; line-height: 1; color: var(--brand-muted); pointer-events: none; white-space: nowrap; transition: top 0.15s ease, font-size 0.15s ease, color 0.15s ease; }
.field input:focus + .field-label, .field input:not(:placeholder-shown) + .field-label { top: 0; font-size: 12px; }
.field input:focus + .field-label { color: var(--brand-input-focus); }
.field input.invalid + .field-label { color: var(--brand-danger); }
.field input:focus, .field input:not(:placeholder-shown) {
  -webkit-mask: linear-gradient(#000 0 0), linear-gradient(#000 0 0) 14px 0 / var(--notch, 0px) 3px no-repeat;
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) exclude, linear-gradient(#000 0 0) 14px 0 / var(--notch, 0px) 3px no-repeat;
}
.field input:focus, .field input:focus-visible { box-shadow: inset 0 0 0 1px var(--brand-input-focus); }
.field input.invalid, .field input.invalid:focus, .field input.invalid:focus-visible { box-shadow: inset 0 0 0 1px var(--brand-danger); }
.recovery-code[role="button"] { cursor: pointer; }
.recovery-code[role="button"]:hover { background: var(--brand-hover); }
#recovery-code-hint.copied { color: var(--brand-success); }
#message.ok { color: var(--brand-success); }
@media (max-width: 480px) { .auth-page-card { margin-block: 24px; } .auth-brand { padding: 24px; } }
