/*
 * profile.css — Phase 3 USER PROFILE page + SITE-WIDE THEME engine + the
 * segmented password-strength meter atom. Built from the existing OSR system:
 * Stone Wall cards (.panel), 1px Mortar borders, border-radius:0, the single
 * accent, white body text. No new visual vocabulary.
 *
 * Three blocks:
 *   1. THEME OVERRIDES — :root[data-theme="…"] swaps --color-accent /
 *      --color-accent-hover / --color-bg site-wide. 'stone' is the default and
 *      re-states the live cornflower tokens so the default app is unchanged.
 *   2. PROFILE PAGE — identity / account / counts / theme cards.
 *   3. PASSWORD METER — reusable segmented bar + rule checklist.
 */

/* ============================================================
   1. SITE-WIDE THEME OVERRIDES
   Each theme replaces the SINGLE accent + the near-black ground (KDL 2026-06-27 §2.1 —
   "no second accent"). Body text stays white by construction, so the accent is
   only ever used for borders / fills / focus rings / large headings, where
   every theme's bright accent on its near-black ground clears the 3:1 UI
   contrast bar comfortably. Values mirror js/theme.js THEMES.
   ============================================================ */

/* 'stone' = baseline. Explicit so a saved 'stone' is identical to the default
   app (the live cornflower tokens), not a surprise. */
:root[data-theme="stone"] {
  --color-accent: #6495ED;
  --color-accent-hover: #7aa8f0;
  --color-bg: #0d0c0a;
}
:root[data-theme="earth"] {
  --color-accent: #e68223;
  --color-accent-hover: #f29a45;
  --color-bg: #120804;
}
:root[data-theme="water"] {
  --color-accent: #32afff;
  --color-accent-hover: #5cc1ff;
  --color-bg: #020810;
}
:root[data-theme="fire"] {
  --color-accent: #ff8212;
  --color-accent-hover: #ff9b3f;
  --color-bg: #160400;
}
:root[data-theme="wind"] {
  --color-accent: #a6b0ec;
  --color-accent-hover: #c0c8f3;
  --color-bg: #0a0b12;
}
:root[data-theme="air"] {
  --color-accent: #3cc4ec;
  --color-accent-hover: #66d2f1;
  --color-bg: #060c16;
}
:root[data-theme="obsidian"] {
  --color-accent: #b066ff;
  --color-accent-hover: #c388ff;
  --color-bg: #050408;
}
:root[data-theme="diamond"] {
  --color-accent: #a8dcff;
  --color-accent-hover: #c6e8ff;
  --color-bg: #080e16;
}
:root[data-theme="jade"] {
  --color-accent: #28d78c;
  --color-accent-hover: #51e0a4;
  --color-bg: #030c06;
}
:root[data-theme="topaz"] {
  --color-accent: #ffd84a;
  --color-accent-hover: #ffe273;
  --color-bg: #0e0a00;
}
:root[data-theme="ruby"] {
  --color-accent: #ff4a64;
  --color-accent-hover: #ff6e83;
  --color-bg: #100208;
}

/* 'custom' (KDL 2026-06-27 theme_contrast_custom_accent.md §2.2 / §2.5). The AUTHORITATIVE
   values are the inline custom properties theme.js paint() sets on <html> from
   the stored accent (accent / accent-hover / bg / surface / surface-hover /
   border + --ink-on-accent). This block only DECLARES the Stone-equivalent
   defaults so a custom theme with NO stored accent (or a parse failure) degrades
   to Stone rather than to an unstyled page — never a broken paint. */
:root[data-theme="custom"] {
  --color-accent: #6495ED;
  --color-accent-hover: #7aa8f0;
  --color-bg: #0d0c0a;
}

/* ============================================================
   2. PROFILE PAGE
   ============================================================ */

.profile {
  max-width: 760px;
}

.profile__loading {
  font-family: var(--font-body);
  font-style: italic;
  color: var(--color-text-muted);
}

/* Each section is a Stone Wall card (the base .panel). The title is a small
   blackletter heading; sr-only on identity (the username is the heading there). */
.profile-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.profile-card__title {
  font-family: var(--font-heading);
  font-size: var(--text-h3);
  color: var(--color-heading);
  margin: 0;
}

/* A card prompting a missing required field (no email yet) carries the live
   accent stripe so it reads as needing attention — not an error (Void Red),
   just "do this". */
.profile-card--alert {
  border-left: 3px solid var(--color-accent);
}

/* --- Identity --- */
.profile-identity {
  flex-direction: row;
  align-items: center;
  gap: var(--space-lg);
}

/* Avatar block (#3a): a 96px frame holding EITHER the monogram glyph OR the
   uploaded image, plus the upload/remove controls beside it. The frame keeps the
   OSR card chrome (Mortar border, 3px accent stripe, near-black ground). */
.profile-identity__avatar-wrap {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
}

.profile-identity__avatar {
  position: relative;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  font-family: var(--font-heading);
  font-size: 3rem;
  line-height: 1;
  color: var(--color-accent);
  overflow: hidden;
}

.profile-identity__monogram[hidden],
.profile-identity__img[hidden] {
  display: none;
}

/* The uploaded image fills the frame, hard-edged (border-radius:0 is global). */
.profile-identity__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.profile-identity__avatar-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
}

/* The upload control is a <label> styled as a button wrapping a visually-hidden
   file input — a native, keyboard-reachable file picker with our chrome. */
.profile-avatar__upload {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

.profile-avatar__upload:focus-within {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.profile-avatar__status {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  margin: 0;
  text-align: center;
}
.profile-avatar__status.is-ok { color: var(--color-accent); }
.profile-avatar__status.is-error { color: var(--color-danger); }

.profile-identity__meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

.profile-identity__name {
  font-family: var(--font-heading);
  font-size: var(--text-h2);
  color: var(--color-heading);
  margin: 0;
  word-break: break-word;
}

.profile-identity__role {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0;
}

/* Last login (Ken request #1): an uppercase muted micro-label + the local-time
   value. Relocated to the Account card (E.12); it now follows the email form, so
   a top margin separates it from the form's actions. The label keeps the
   heading-ui idiom; the value drops the tracking/transform so the timestamp
   reads cleanly. */
.profile-account__lastlogin {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: var(--space-md) 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs);
}

.profile-account__lastlogin-label {
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
}

.profile-account__lastlogin-value {
  font-family: var(--font-mono);
  letter-spacing: normal;
  text-transform: none;
  color: var(--color-text);
}

/* --- Email --- */
.profile-email {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.profile-email__help {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--color-text-muted);
  margin: 0;
}

.profile-email__actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.profile-email__status,
.profile-pw__status {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  margin: 0;
}

.profile-email__status.is-ok,
.profile-pw__status.is-ok { color: var(--color-accent); }

.profile-email__status.is-error,
.profile-pw__status.is-error { color: var(--color-danger); }

/* --- Change password --- */
.profile-pw {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  max-width: 28rem;
}

.profile-pw__actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.pw-confirm__msg {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  margin: var(--space-xs) 0 0;
  min-height: 1.1em;
}
.pw-confirm__msg.is-ok { color: var(--color-accent); }
.pw-confirm__msg.is-error { color: var(--color-danger); }

/* --- Counts --- */
.profile-counts__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: var(--space-sm);
}

.profile-counts__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-md);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
}

/* Clickable count tile (#2a) — a button that navigates to its module. Reset the
   button chrome, keep the tile look, and add hover/focus affordances so it reads
   as actionable (a control, not a static stat). */
.profile-counts__tile--link {
  appearance: none;
  cursor: pointer;
  font: inherit;
  text-align: center;
  transition:
    border-color var(--transition-fast),
    background-color var(--transition-fast);
}

.profile-counts__tile--link:hover {
  background-color: var(--color-surface-hover);
  border-color: var(--color-accent);
}

.profile-counts__tile--link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.profile-counts__num {
  font-family: var(--font-mono);
  font-size: 2.25rem;
  line-height: 1;
  color: var(--color-text);
}

.profile-counts__label {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

/* --- Theme picker --- */
.profile-theme__intro {
  font-family: var(--font-body);
  color: var(--color-text-muted);
  margin: 0;
}

.profile-theme__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: var(--space-sm);
}

.profile-theme__swatch {
  appearance: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm);
  background-color: var(--color-surface);
  border: 2px solid transparent;
  transition:
    border-color var(--transition-fast),
    background-color var(--transition-fast);
}

.profile-theme__swatch:hover {
  background-color: var(--color-surface-hover);
}

/* Selected swatch: a 2px accent border (a ring, not a glow — KDL 2026-06-27 Do Not #5). */
.profile-theme__swatch.is-active {
  border-color: var(--color-accent);
}

.profile-theme__swatch:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* The chip previews the theme's actual ground + accent (a mini die face): the
   per-theme bg from --swatch-bg, a centered "gem" in --swatch-accent. Honest
   preview — what you pick is what the site becomes. */
.profile-theme__chip {
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--swatch-bg);
  border: 1px solid var(--color-border);
}

.profile-theme__gem {
  width: 42%;
  height: 42%;
  background:
    radial-gradient(circle at 35% 30%,
      color-mix(in srgb, var(--swatch-accent) 85%, white) 0%,
      var(--swatch-accent) 55%,
      color-mix(in srgb, var(--swatch-accent) 60%, black) 100%);
  /* Hard-edged diamond facet — no rounding, matches the OSR system. */
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}

.profile-theme__name {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.profile-theme__swatch.is-active .profile-theme__name {
  color: var(--color-accent);
}

.profile-theme__selected {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text);
  margin: 0;
  min-height: 1.2em;
}

/* --- Custom theme (#7) --- */
/* The Custom swatch gem shows the current accent as a solid chip rather than the
   faceted preset gem — so it reads as "your color", not a fixed preset. */
.profile-theme__swatch--custom .profile-theme__gem {
  background: var(--swatch-accent);
}

.profile-theme__swatch--custom[hidden] { display: none; }

/* The control row revealed when Custom is selected — a native color input + a
   hex text field, side by side, plus a help line. Not a modal (KDL 2026-06-27 §2.4). */
.profile-theme__custom {
  display: block;
}
.profile-theme__custom[hidden] { display: none; }

.profile-theme__custom-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.profile-theme__custom-controls {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Native color input as a hard-edged square chip with a Mortar border (KDL 2026-06-27
   §2.4). Strip the platform swatch padding so the color fills the chip. */
.profile-theme__color {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--color-border);
  background: none;
  cursor: pointer;
  flex: 0 0 auto;
}
.profile-theme__color::-webkit-color-swatch-wrapper { padding: 0; }
.profile-theme__color::-webkit-color-swatch { border: none; }
.profile-theme__color::-moz-color-swatch { border: none; }
.profile-theme__color:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.profile-theme__hex {
  font-family: var(--font-mono);
  max-width: 9rem;
  text-transform: lowercase;
}

.profile-theme__hex-help {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--color-text-muted);
  margin: 0;
}
.profile-theme__hex-help.is-error {
  color: var(--color-danger);
  font-style: normal;
}

/* ============================================================
   3. PASSWORD-STRENGTH METER (reusable atom)
   Segmented hard-edged bar — strength shown by how many segments fill (accent),
   NOT by hue (KDL 2026-06-27 §4 — no red→green gradient). The word label + rule checklist
   carry the real signal for screen readers; the bar is aria-hidden.
   ============================================================ */

.pw-meter {
  display: flex;
  gap: 3px;
  margin-top: var(--space-xs);
}

.pw-meter__seg {
  flex: 1 1 0;
  height: 4px;
  background-color: var(--color-border);
  transition: background-color var(--transition-fast);
}

.pw-meter__seg.is-on {
  background-color: var(--color-accent);
}

.pw-meter__label {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
  margin: var(--space-xs) 0 0;
  min-height: 1.1em;
}

.pw-rules {
  list-style: none;
  margin: var(--space-sm) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.pw-rules__item {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
}

.pw-rules__item.is-met {
  color: var(--color-text);
}

.pw-rules__mark {
  color: var(--color-text-muted);
  font-family: var(--font-mono);
}

.pw-rules__item.is-met .pw-rules__mark {
  color: var(--color-accent);
}

/* ============================================================
   4. DICE CARD (§7) — style previews + effects + laser number color
   Mirrors the Theme picker's card/field/radiogroup vocabulary. The three
   style tiles are a radiogroup with a live mini-preview each; the selected
   tile carries the 2px accent ring (a ring, not a glow — KDL 2026-06-27 Do Not #5).
   ============================================================ */

.profile-dice__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* A non-<label> group heading (Style / Laser number color) styled like a
   field label so the controls read as a labeled group. */
.profile-dice__legend {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.profile-dice__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: var(--space-sm);
}

.profile-dice__tile {
  appearance: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm);
  background-color: var(--color-surface);
  border: 2px solid transparent;
  transition:
    border-color var(--transition-fast),
    background-color var(--transition-fast);
}

.profile-dice__tile:hover {
  background-color: var(--color-surface-hover);
}

.profile-dice__tile.is-active {
  border-color: var(--color-accent);
}

.profile-dice__tile:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* The preview surface: a square on the near-black die ground. The laser engine
   appends an absolutely-positioned canvas into this box (position: relative). */
.profile-dice__preview {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #0d0c0a;
  border: 1px solid var(--color-border);
  overflow: hidden;
}

/* 3D Polyhedral preview: the hero-image PNG tinted via currentColor mask + a
   centred sample number, echoing dice_test's data-style="3d" tile. */
.profile-dice__preview--3d {
  color: var(--color-accent);
}

.profile-dice__hero {
  position: absolute;
  inset: 8%;
  background-color: currentColor;
  -webkit-mask-image: var(--hero-img);
  mask-image: var(--hero-img);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.profile-dice__hero-num {
  position: relative;
  z-index: 1;
  font-family: var(--font-heading-ui);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--color-bg);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

/* Rendered preview: the stone die material (a warm forge ground) + a number,
   echoing dice_test's default .die-tile look. */
.profile-dice__preview--rendered {
  background:
    radial-gradient(ellipse 55% 45% at 50% 20%, rgba(255, 255, 255, 0.12) 0%, transparent 65%),
    radial-gradient(ellipse 100% 100% at 50% 60%, rgba(0, 0, 0, 0.22) 0%, transparent 80%),
    linear-gradient(178deg, #4a4232 0%, #382c1e 38%, #2e2218 100%);
  box-shadow: inset -2px -2px 0 rgba(0, 0, 0, 0.50), inset 0 0 24px rgba(0, 0, 0, 0.26);
}

.profile-dice__rendered-num {
  font-family: var(--font-heading-ui);
  font-weight: 700;
  font-size: 1.6rem;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 0 6px rgba(240, 200, 90, 0.4);
}

.profile-dice__name {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

.profile-dice__tile.is-active .profile-dice__name {
  color: var(--color-accent);
}

/* Effect selects: constrain width like other short-option selects. */
.profile-dice__select {
  max-width: 16rem;
}

/* --- Laser number color --- */
.profile-dice__numgroup {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.profile-dice__numradio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-body);
  color: var(--color-text);
  cursor: pointer;
}

.profile-dice__numradio input {
  accent-color: var(--color-accent);
  cursor: pointer;
}

.profile-dice__numcustom {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}
.profile-dice__numcustom[hidden] { display: none; }

.profile-dice__hex {
  max-width: 9rem;
}

/* Greyed state when the active style is not Laser: the control persists but is
   inert and visibly de-emphasized, with the "applies to Laser" note. */
.profile-dice__numcolor.is-disabled {
  opacity: 0.5;
}

.profile-dice__numnote {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-style: italic;
  color: var(--color-text-muted);
  margin: 0;
}
.profile-dice__numnote[hidden] { display: none; }

.profile-dice__status {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
  margin: 0;
  min-height: 1.2em;
}
.profile-dice__status.is-ok { color: var(--color-text); }
.profile-dice__status.is-error { color: var(--color-danger); }

/* ============================================================
   Discord connection (Surface 1) — the link/unlink card. Reuses .profile-card
   chrome. The status line carries a small Discord glyph (currentColor) + the
   connected username (set via textContent — foreign data). The Connect / Unlink
   controls are the app's themed .btn--secondary.
   ============================================================ */

.profile-discord__status-line {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 0 var(--space-md);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  color: var(--color-text);
}

.profile-discord__name {
  color: var(--color-accent);
  word-break: break-word;
}

.profile-discord__glyph {
  display: inline-flex;
  align-items: center;
  color: var(--color-accent);
  flex: 0 0 auto;
}

.profile-discord__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

.profile-discord__connect {
  text-decoration: none;
}

.profile-discord__msg {
  margin: 0;
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
  min-height: 1.2em;
}
.profile-discord__msg.is-ok { color: var(--color-text); }
.profile-discord__msg.is-error { color: var(--color-danger); }
.profile-discord__msg[hidden] { display: none; }

.profile-discord__state[hidden] { display: none; }

/* ============================================================
   Foundry Connector (K-SEC-18) — per-user bearer-key management. Reuses the
   .profile-card chrome. The plaintext key is shown ONCE in a readonly field;
   the warning is a high-emphasis line. Rotate/Revoke are the app's themed
   .btn--secondary / .btn--danger; destructive intent is confirmed via the
   shared action-modal, not styled away here.
   ============================================================ */

.profile-connector[hidden] { display: none; }

.profile-connector__lede {
  margin: 0 0 var(--space-md);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  color: var(--color-text);
}

.profile-connector__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

/* Show-once reveal: a bordered, slightly inset block so it reads as a distinct,
   transient "act now" surface. The accent border + warn line carry the urgency;
   color is never the sole cue (the warn text states it outright). */
.profile-connector__reveal {
  border: 1px solid var(--color-accent);
  padding: var(--space-md);
  margin: 0 0 var(--space-md);
}
.profile-connector__reveal[hidden] { display: none; }

.profile-connector__warn {
  margin: 0 0 var(--space-md);
  font-family: var(--font-heading-ui);
  font-size: var(--text-base);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-danger);
  font-weight: 600;
}

.profile-connector__key-row {
  display: flex;
  align-items: stretch;
  gap: var(--space-sm);
}

.profile-connector__key {
  flex: 1 1 auto;
  font-family: var(--font-mono, monospace);
  word-break: break-all;
}

.profile-connector__copy {
  flex: 0 0 auto;
}

.profile-connector__copied {
  margin: var(--space-sm) 0 0;
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text);
}
.profile-connector__copied[hidden] { display: none; }

/* Active-key meta — a tight definition list (Status / Created / Last used). */
.profile-connector__meta {
  margin: 0 0 var(--space-md);
  display: grid;
  gap: var(--space-xs);
}
.profile-connector__meta-row {
  display: flex;
  gap: var(--space-sm);
  align-items: baseline;
}
.profile-connector__meta dt {
  flex: 0 0 7rem;
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
}
.profile-connector__meta dd {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  word-break: break-word;
}

.profile-connector__badge {
  display: inline-block;
  padding: 0.1em 0.6em;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
}

.profile-connector__msg {
  margin: var(--space-md) 0 0;
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
  min-height: 1.2em;
}
.profile-connector__msg.is-ok { color: var(--color-text); }
.profile-connector__msg.is-error { color: var(--color-danger); }
.profile-connector__msg[hidden] { display: none; }

.profile-connector__state[hidden] { display: none; }

/* Connection instructions — a muted, ordered how-to under the controls. */
.profile-connector__howto {
  margin-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-md);
}
.profile-connector__howto-title {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-heading-ui);
  font-size: var(--text-base);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text);
}
.profile-connector__steps {
  margin: 0;
  padding-left: 1.4em;
  display: grid;
  gap: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--lh-body);
  color: var(--color-text);
}
.profile-connector__url {
  font-family: var(--font-mono, monospace);
  color: var(--color-accent);
  word-break: break-all;
}

/* Manifest URL row: the click-to-copy module.json path + its Copy button. The
   code span takes the row and wraps; the button stays beside it and drops below
   on narrow widths. */
.profile-connector__manifest {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-xs);
}
.profile-connector__manifest .profile-connector__url {
  /* Sit on the Stone Wall surface so the monospace path reads as a copyable
     code chip, not loose inline text. */
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  padding: 0.15em 0.4em;
}
.profile-connector__manifest .profile-connector__copy {
  flex: 0 0 auto;
}

/* ============================================================
   Responsive
   ============================================================ */

@media (max-width: 600px) {
  .profile-identity {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Touch-target floor (mobile-optimization Phase 3, 2026-06-14): guarantee the
   dice-preset tile is at least a 44px tap target on touch widths. The tile is
   already tall (square preview + label), but this guards against the smallest
   presets/short labels. Desktop density unchanged (rule is mobile-only). */
@media (max-width: 700px) {
  .profile-dice__tile {
    min-height: 44px;
  }
}

/* ============================================================
   Hardcore mode toggle (ADDENDUM 2026-06-21b #7)
   ------------------------------------------------------------
   A native checkbox + label inside a standard .profile-card.
   The native control carries the semantics, keyboard support,
   and accessible name; accent-color paints it on-theme to match
   the bestiary/char-dashboard checkbox idiom. The whole label is
   the click target (≥44px tall) so the row is easy to hit.
   ============================================================ */
.profile-hardcore__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 44px;
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--color-text);
}

.profile-hardcore__input {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.profile-hardcore__label {
  font-size: 1rem;
  line-height: 1.3;
}

.profile-hardcore__status {
  margin-top: var(--space-sm);
}

.profile-hardcore__status.is-error {
  color: var(--color-danger, #c0563b);
}

.profile-hardcore__status.is-ok {
  color: var(--color-accent);
}

/* ============================================================
   VISIBLE SECTIONS (section_visibility_toggles, 2026-06-27)
   Per-user nav-visibility switches. Reuses the .profile-card chrome and the
   .profile-hardcore checkbox idiom (44px hit target, accent-colored native
   checkbox). Switches are grouped by nav menu in <fieldset>/<legend> blocks; the
   switches within a group lay out in a responsive auto-fill grid.
   ============================================================ */
.profile-sections__groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-sm);
}

.profile-sections__group {
  margin: 0;
  padding: 0;
  border: 0;
}

.profile-sections__legend {
  padding: 0;
  margin-bottom: var(--space-xs);
  font-family: var(--font-heading, var(--font-body));
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted, var(--color-text));
}

.profile-sections__group > .profile-sections__toggle {
  display: inline-flex;
}

.profile-sections__group {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-xs) var(--space-md);
}

/* The legend should span the whole grid row, not sit in a single column. */
.profile-sections__legend {
  grid-column: 1 / -1;
}

.profile-sections__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 44px;
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--color-text);
}

.profile-sections__input {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.profile-sections__label {
  font-size: 1rem;
  line-height: 1.3;
}

.profile-sections__status {
  margin-top: var(--space-sm);
}

.profile-sections__status.is-error {
  color: var(--color-danger, #c0563b);
}

.profile-sections__status.is-ok {
  color: var(--color-accent);
}

/* ============================================================
   YOUR DATA / DANGER ZONE (batch 6, KDL 2026-06-27)
   The export (safe) + delete-all (destructive) panel. Reuses .profile-card
   chrome. The whole panel carries a danger left-border so a wipe-everything
   control is visually set apart from routine saves; within it, the destructive
   row is further marked. The export row is the app's neutral .btn--secondary;
   the delete row is .btn--danger. The typed-confirm field lives inside the
   shared .action-modal chrome (no new modal scaffolding).
   ============================================================ */
.profile-data {
  border-left: 3px solid var(--color-danger);
}

.profile-data__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
}

/* The first row sits right under the intro — no top divider needed. */
.profile-data__row:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.profile-data__row-text {
  flex: 1 1 18rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.profile-data__row-title {
  font-family: var(--font-heading-ui);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  margin: 0;
}

.profile-data__row-title--danger {
  color: var(--color-danger);
}

.profile-data__row-help {
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--color-text-muted);
  margin: 0;
}

.profile-data__row-actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-xs);
}

.profile-data__status {
  font-size: 0.85rem;
  margin: 0;
  text-align: right;
  max-width: 16rem;
}

.profile-data__status.is-error { color: var(--color-danger); }
.profile-data__status.is-ok { color: var(--color-accent); }

/* On narrow viewports the action stacks under its description and the button
   spans the row so the target is comfortable on touch. */
@media (max-width: 32rem) {
  .profile-data__row-actions {
    align-items: stretch;
    width: 100%;
  }
  .profile-data__status { text-align: left; max-width: none; }
}

/* The typed-confirmation field inside the destructive modal. Sits below the
   warning copy with a little breathing room; the input is monospaced so the
   confirmation word is unambiguous as the user types it. */
.profile-typed-confirm__field {
  margin-top: var(--space-sm);
}

.profile-typed-confirm__input {
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
}

.profile-typed-confirm__field .field__help {
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--color-text-muted);
  margin: var(--space-xs) 0 0;
}

.profile-typed-confirm__field .field__help strong {
  font-family: var(--font-mono);
  color: var(--color-text);
}

/* ============================================================
   Friends (Email v2 §D) — invite by email + pending + accepted
   ============================================================ */

.profile-friends__invite {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0 0 var(--space-md);
}

.profile-friends__invite-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

.profile-friends__invite-status {
  margin: 0;
  font-size: var(--text-sm);
}
.profile-friends__invite-status.is-ok { color: var(--color-accent); }
.profile-friends__invite-status.is-error { color: var(--color-danger); }

.profile-friends__group {
  margin: var(--space-md) 0 0;
}

.profile-friends__subtitle {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-xs);
}

.profile-friends__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.profile-friends__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 2px);
  background: var(--color-surface, transparent);
}

.profile-friends__name {
  font-weight: 600;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.profile-friends__item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.profile-friends__item-note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
}

.profile-friends__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-style: italic;
}

.profile-friends__status {
  margin: var(--space-sm) 0 0;
  font-size: var(--text-sm);
}
.profile-friends__status.is-error { color: var(--color-danger); }

/* ----- friend sharing: Shared with me / Shared by me (Feature A) ----- */
.profile-friends__share-list {
  list-style: none;
  margin: var(--space-xs) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.profile-friends__share-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 2px);
  background: var(--color-surface, transparent);
}

.profile-friends__share-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}

.profile-friends__share-name {
  font-weight: 600;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.profile-friends__share-sub {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  overflow-wrap: anywhere;
}
