/* =======================================================================
   CodeDesk — THEME.CSS
   Master style sheet controlling UI variables, theming, and component look.
   Author: Jacob Eugene Henderson
   -----------------------------------------------------------------------
   STRUCTURE OVERVIEW
   -----------------------------------------------------------------------
   1.  CONTROL PANEL — BASE (dark mode default)
         • Global design tokens and CSS variables (color, radii, density, motion)
         • Defines reusable Material-inspired system values (md-sys-color-* etc.)
   2.  GLOBAL SCAFFOLD
         • Body background gradients, theme grid overlay, layout padding
   3.  CARDS / SURFACES
         • Card containers, elevation shadows, stepper highlights
   4.  CONTROLS
         • Inputs, selects, buttons, and top-bar menu items
         • Includes hover/focus, emoji picker, and color-chip definitions
   5.  PREVIEW LAYOUT
         • QR preview area, SVG mount, transparent-frame styling
   6.  ARROWS
         • Navigation arrows for QR subtype switching
   7.  FOOTER
         • Fixed footer gradient bar and copyright text
   8.  THEME MODES
         • :root.light, :root.hc, and reduced-motion overrides
   9.  UTILITIES / OVERRIDES (sandbox)
         • Temporary tweaks, experimental features, or future controls
   -----------------------------------------------------------------------
   NOTES
   -----------------------------------------------------------------------
   • Variables follow Material Design token conventions where possible.
   • All custom properties begin with `--md-sys-`, `--ui-`, or `--qr-` prefixes.
   • JS can read certain variables via `getComputedStyle()` (e.g., --export-*).
   • To add new features, prefer creating new tokens at the top-level :root.
   • For experiments or nonstandard styling, append at the bottom section (9).
   ======================================================================= */

/* =========================
   1. CONTROL PANEL — BASE
========================= */
:root{

  /* ----- Header ----- */
  --header-h: 56px;

  /* ----- Ascend token aliases (no CodeDesk branding here) ----- */
  --md-sys-color-primary:          var(--ascend-app-accent, var(--ascend-color-accent, #4fd1c5));
  --md-sys-color-primary-hover:    color-mix(in oklab, var(--md-sys-color-primary) 86%, white);
  --md-sys-color-primary-pressed:  color-mix(in oklab, var(--md-sys-color-primary) 78%, black);
  --md-sys-color-on-primary:       #ffffff;

  /* QR frame cosmetics (Ascend-owned) */
  --stage-frame:   var(--ascend-stage-frame, #1ff0ff);
  --stage-frame-w: var(--ascend-stage-frame-w, 3px);

  /* Surfaces & text (inherit Ascend app shell)
     IMPORTANT: include fallbacks so light-mode doesn't go "empty" if Ascend tokens aren't present. */
  --md-sys-color-background:       var(--ascend-app-bg, #e7ecf5);
  --md-sys-color-on-background:    var(--ascend-app-text-main, #020617);
  --md-sys-color-surface:          var(--ascend-app-surface, #ffffff);
  --md-sys-color-on-surface:       var(--ascend-app-text-main, #020617);
  --md-sys-color-surface-variant:  var(--ascend-control-bg, #ffffff);
  --md-sys-color-muted:            var(--ascend-app-text-muted, #64748b);

  /* Strokes (inherit Ascend app shell) */
  --md-sys-color-outline:          var(--ascend-app-border, rgba(15, 23, 42, 0.22));
  --md-sys-color-outline-variant:  color-mix(in oklab, var(--md-sys-color-outline) 70%, var(--md-sys-color-primary) 30%);

  /* ---------------------------------------------------------
     UI ALIASES (authoritative, applies in BOTH dark + light)
     Without these, cards/headers can go transparent in CodeDesk.
     --------------------------------------------------------- */
  --ui-surface:         var(--md-sys-color-surface);
  --ui-surface-variant: var(--md-sys-color-surface-variant);
  --ui-stroke:          var(--md-sys-color-outline);
  --ui-stroke-hover:    var(--md-sys-color-outline-variant);
  --ui-focus-ring:      var(--md-sys-color-primary);
  --ui-glow-color:      var(--md-sys-color-primary);
  
  /* QR frame (Transparent mode) */
  --qr-stroke-color:   rgba(139,92,246,.70);
  --qr-stroke-width:   1;
  --qr-stroke-glow:    0 0 18px rgba(139,92,246,.28);

  /* ----- Density / Compact scale ----- */
  --density-scale: 1;
  --density-control-h-base: 2.25rem;
  --density-gap-base: .75rem;
  --density-control-h: calc(var(--density-control-h-base) * var(--density-scale));
  --density-gap:       calc(var(--density-gap-base) * var(--density-scale));

  /* ----- Focus ring (consistent keyboard focus) ----- */
  --focus-ring-width: 2px;
  --focus-ring-color: color-mix(in oklab, var(--md-sys-color-primary) 35%, transparent);

  /* ----- Motion scale (global speed) ----- */
  --motion-scale: 1;
  --motion-duration-1-base: 120ms;
  --motion-duration-2-base: 180ms;
  --motion-duration-1: calc(var(--motion-duration-1-base) * var(--motion-scale));
  --motion-duration-2: calc(var(--motion-duration-2-base) * var(--motion-scale));
  --motion-ease: cubic-bezier(.2,.6,.2,1);

  /* ----- Export defaults (read by JS) ----- */
  --export-png-scale: 3;
  --export-filename: "Codedesk";

  /* ----- Grid overlay knobs (Ascend-owned cosmetics) ----- */
  /* Unification layer: provide Ascend-compatible defaults derived from the canonical Ascend shell tokens */
  --ascend-grid-size:         var(--ascend-grid-major, 48px);
  --ascend-grid-opacity:      1;
  --ascend-grid-glow-color:   var(--ascend-grid-line-color-soft, rgba(79, 209, 197, 0.22));
  --ascend-grid-glow-opacity: 1;
  --ascend-grid-glow-blur:    0px;
  --ascend-grid-vignette-strength: 0.20;
  --ascend-grid-vignette-size:     var(--ascend-grid-wash-stop, 55%);
  --ascend-grid-vignette-y:        top;

  --grid-size:              var(--ascend-grid-size, 48px);
  --grid-opacity:           var(--ascend-grid-opacity, 1);
  --grid-line-color:        var(--ascend-grid-line-color, rgba(0, 81, 255, 0.35));
  --grid-glow-color:        var(--ascend-grid-glow-color, rgba(79, 209, 197, 0.22));
  --grid-glow-opacity:      var(--ascend-grid-glow-opacity, 1);
  --grid-glow-blur:         var(--ascend-grid-glow-blur, 0px);
  --grid-vignette-strength: var(--ascend-grid-vignette-strength, 0.20);
  --grid-vignette-size:     var(--ascend-grid-vignette-size, 55%);
  --grid-vignette-y:        var(--ascend-grid-vignette-y, top);

  /* Hover / focus glow knobs (Ascend-owned cosmetics) */
  --hover-glow-color: var(
    --ascend-hover-glow-color,
    color-mix(in oklab, var(--md-sys-color-primary) 30%, transparent)
  );
  --hover-glow-blur:  var(--ascend-hover-glow-blur, 8px);
  --focus-glow-blur:  var(--ascend-focus-glow-blur, 10px);

  /* Shared chevron for top controls */
  --chev-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='white'><path d='M5.23 7.21a.75.75 0 011.06.02L10 10.17l3.71-2.94a.75.75 0 111.04 1.08l-4.23 3.35a.75.75 0 01-.96 0L5.21 8.31a.75.75 0 01.02-1.1z'/></svg>");
  
  /* Phone radius... */
  --phone-radius: 22px;

  /* Keep all major card rounding on the same knob */
  --shape-corner-lg: var(--phone-radius);

  /* Arrows placement... */
  --edge-gutter: clamp(24px, 2vw, 24px);

  /* Footer height token */
    --footer-h: 72px;

  /* … existing vars … */
  --stack-gap: 0rem;        /* unify spacing rhythm */

  /* ----- BG CARD STROKE (filled mode) — Ascend-owned cosmetics ----- */
  --bg-card-stroke-color: var(--ascend-bg-card-stroke-color, hsl(179, 100%, 38%));
  --bg-card-stroke-width: var(--ascend-bg-card-stroke-width, 1px);
  --bg-card-stroke-glow:  var(--ascend-bg-card-stroke-glow, 0 0 10px rgba(0,240,200,.35));

    /* Featured / open card accent (default = global lilac story) */
  --featured-stroke-width: 1px;
  --step-color-primary: var(--md-sys-color-primary);
  --featured-stroke-color: color-mix(in oklab, var(--step-color-primary) 45%, transparent);
  --featured-stroke-glow: none;

  /* Open step fills (used only inside cards) */
  --step-header-open-bg: color-mix(in oklab, var(--ui-surface) 85%, var(--step-color-primary) 15%);
  --step-card-open-bg:   color-mix(in oklab, var(--ui-surface) 94%, var(--step-color-primary) 6%);

  --stepper-stroke-closed: var(--md-sys-color-outline);
 
}

  /* ==========================================================
   SECTION COLOR THEMES
   Uses existing brand knobs: --brand-h / --brand-s / --brand-l
   ========================================================== */

/* shared sticky offset */
.stage-stick {
  position: sticky;
  top: var(--header-h);
}

/* =========================
   2. GLOBAL SCAFFOLD (functional only)
========================= */

html, body{
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto; /* allow native scroll + middle-click autoscroll */
}

body{
  margin: 0;
  color: var(--md-sys-color-on-background);

  /* Ascend app grid (same as Copydesk) */
  background-color: var(--ascend-grid-bg, var(--md-sys-color-background));
  background-image:
    linear-gradient(to right, var(--ascend-grid-line-color, rgba(0, 81, 255, 0.35)) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ascend-grid-line-color, rgba(0, 81, 255, 0.35)) 1px, transparent 1px),
    linear-gradient(to right, var(--ascend-grid-line-color-soft, rgba(79, 209, 197, 0.22)) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ascend-grid-line-color-soft, rgba(79, 209, 197, 0.22)) 1px, transparent 1px),
    radial-gradient(circle at top, var(--ascend-grid-wash-color, rgba(79, 209, 197, 0.20)), transparent var(--ascend-grid-wash-stop, 55%));
  background-size:
    var(--ascend-grid-major, 48px) var(--ascend-grid-major, 48px),
    var(--ascend-grid-major, 48px) var(--ascend-grid-major, 48px),
    var(--ascend-grid-minor, 12px) var(--ascend-grid-minor, 12px),
    var(--ascend-grid-minor, 12px) var(--ascend-grid-minor, 12px),
    auto;
  background-attachment: fixed;
  background-repeat: repeat;

  position: relative;
  isolation: isolate;
}

/* Ensure the actual UI sits above any upstream decorative layers */
#app, #root, main, header, footer, .app, .shell, .wrap, #stepper, #qrPreview, .preview-stage{
  position: relative;
  z-index: 1;
}

/* =========================
   3. CARDS / SURFACES
========================= */
.card{
  background: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--phone-radius);
  box-shadow: var(--elevation-2);
}
.step-card{ overflow:hidden; } /* remove square border artifact on rounded cards */

/* Open card highlight */
#stepper>div{ transition:background-color .15s,border-color .15s; }
#stepper .step-header{ transition:background-color .15s,border-color .15s,color .15s; }

/* Collapsed header: subtle tint + crisp edge (reuses existing knobs) */
#stepper > .step-card:not(.is-open) .step-header{
  background: transparent;
  border: 0;
  box-shadow: none;
}

/* Hover tint must hit the FULL header shell (wrap), not just the left button chunk */
#stepper > div:not(.is-open) .step-header-wrap:hover{
  background: color-mix(in oklab, var(--ui-surface) 88%, var(--step-color-primary) 12%);
}

/* Caption has no wrap — tint the button itself */
#stepper > div[data-step="caption"]:not(.is-open) > .step-header:hover{
  background: color-mix(in oklab, var(--ui-surface) 88%, var(--step-color-primary) 12%);
}

#stepper>div.is-open .step-header {
  border-bottom: var(--featured-stroke-width) solid var(--featured-stroke-color);
  background: var(--step-header-open-bg); /* ✅ selected = light blue */
  backdrop-filter: saturate(1.1) blur(6px);
}

/* ✅ Open header slab: same height as closed, flat bottom corners */
#stepper > div.is-open .step-header-wrap{
  min-height: 3.4rem;
  border-radius: var(--phone-radius) var(--phone-radius) 0 0;
}

/* When a step is open, its outer shell adopts the local step color story */
.step-card.is-open{
  --ui-stroke: color-mix(in oklab, var(--step-color-primary) 40%, transparent);
  --ui-stroke-hover: color-mix(in oklab, var(--step-color-primary) 60%, transparent);

  /* ✅ card stays white; only the header stripe gets the blue */
  background: var(--ui-surface);
  border-color: var(--featured-stroke-color);
  box-shadow: var(--featured-stroke-glow);
}

/* Inputs & labels inside the active step pick up the section accent */
#stepper > div.is-open input:not([type="range"]),
#stepper > div.is-open select,
#stepper > div.is-open textarea,
#stepper > div.is-open .control,
#stepper > div.is-open .topctl {
  border-color: color-mix(in oklab, var(--step-color-primary) 40%, transparent);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--step-color-primary) 40%, transparent) inset;
}

#stepper > div.is-open label,
#stepper > div.is-open .field-label {
  color: color-mix(in oklab, var(--md-sys-color-on-surface) 86%, var(--step-color-primary) 14%);
}

/* Mechanicals (open): unified stripe, full-bleed to card edge */
.step-card[data-step="mechanicals"].is-open .step-header-wrap {
  background: var(--step-header-open-bg);
  border-bottom: 0 !important;
  position: relative;

  /* harden full-bleed geometry */
  margin: 0;
  width: 100%;

  /* ✅ match closed indentation */
  padding-inline: 1.25rem;
}

.step-card[data-step="mechanicals"].is-open .step-header {
  background: transparent !important;
  border-bottom: 0 !important;
}

/* Single thin rule painted behind ECC pill (visual match with Caption) */
.step-card[data-step="mechanicals"].is-open .step-header-wrap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--ui-stroke);
  pointer-events: none;
}

/* Mechanicals body should match other panels’ surface */
.step-card[data-step="mechanicals"] [data-step-panel]{
  background: var(--ui-surface-variant);
}

/* Nudge the panel up 1px so it tucks under the header line (no step) */
.step-card[data-step="mechanicals"].is-open [data-step-panel]{
  margin-top: -1px;
}

/* Keep it “alive” even if something disables it */
#codedeskFilename:disabled{
  opacity: 1;
  -webkit-text-fill-color: currentColor;
  cursor: text;
}

/* Optional: when locked, keep the filename fully vivid even if other UI dims */
body.codedesk-locked #codedeskFilename{
  opacity: 1 !important;
  filter: none !important;
}

/* The stepper is the scroll container + the gap owner */
#stepper{
  display:flex;
  flex-direction:column;
  height:auto;
  overflow:visible;
  gap: var(--stack-gap);
  min-width:0; width:100%; max-width:720px; margin-inline:auto;
  scroll-padding-top: calc(var(--header-h,56px) + var(--preview-overlap, 200px));
  padding-bottom: 16px; /* footer removed; keep a little breathing room */
}

#captionEl{
  white-space: pre-wrap;        /* 🔑 preserves \n + collapses extra spaces */
  overflow-wrap: anywhere;      /* allow breaking long words/URLs */
  word-break: break-word;       /* legacy safety */
  hyphens: auto;                /* prettier wrapping for long words */
  text-wrap: balance;           /* nicer line breaks when multi-line */
}

#captionBox{
  max-width: 90%;
  margin: .5rem auto 0;
   max-height: clamp(3rem, 16vh, 220px);
  overflow: auto;
  scrollbar-width: thin;
}
#captionBox::-webkit-scrollbar{ width: 8px; }
#captionBox::-webkit-scrollbar-thumb{ border-radius: 999px; background: var(--ui-stroke-hover); }

#captionEl{
  font-size: clamp(.9rem, 2.2vw, 1.5rem);
  line-height: 1.15;
}

.step-card[data-step="caption"] .caption-toggle-row { justify-self: start; }

.step-card[data-step="caption"] label:has(#campaign),
.step-card[data-step="caption"] label:has(#captionBody){
  display: block;
  width: 100%;
}

.step-card[data-step="caption"] label:has(#showCaption){
  justify-self: start;
}

/* Ensure the caption text field spans the whole card */
.step-card[data-step="caption"] label:has(#campaign){
  display: grid;                /* keep label as a block wrapper */
  grid-template-columns: 1fr;   /* kill any leftover two-column form rules */
}
.step-card[data-step="caption"] #campaign{
  width: 100%;
}

/* Put the toggle on its own row under the input, left-aligned */
.step-card[data-step="caption"] #showCaption,
.step-card[data-step="caption"] [for="showCaption"]{
  justify-self: start;
}

/* (Optional) tighten the vertical rhythm of the toggle row */
.step-card[data-step="caption"] [for="showCaption"]{
  line-height: 1.2;
}

/* Caption text input: single row, full width */
#campaign{
  display:block;
  width: 100%;
  height: var(--density-control-h);
  line-height: var(--density-control-h);
  padding: 0 .75rem;
  resize: none;
  overflow: hidden;
  box-sizing: border-box;
  box-shadow: none;       /* Focus Ring */
}

/* Caption body input: multi-line, matching shell */
#captionBody{
  display:block;
  width: 100%;
  min-height: calc(var(--density-control-h) * 1.5);
  padding: 0.5rem .75rem;
  line-height: 1.3;
  resize: vertical;
  overflow: auto;
  box-sizing: border-box;
  box-shadow: none;
}

/* Header slab must be full-bleed; padding moves to title only */
.step-card .step-header {
  padding: 0;
}

.step-card [data-step-panel]{
  padding-top: 0.75rem;  /* panels had no top padding */
}

/* Optional: give the very first control inside a panel a bit of air */
.step-card [data-step-panel] > :first-child {
  margin-top: 0.25rem;
}

/* Base step card + header use token surfaces (theme-aware) */
.step-card{
  background: var(--ui-surface);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--phone-radius);
  box-shadow: var(--elevation-2);
}

/* When a step is open, its outer shell adopts the local step color story */
#stepper .step-card.is-open{
  --ui-stroke: color-mix(in oklab, var(--step-color-primary) 40%, transparent);
  --ui-stroke-hover: color-mix(in oklab, var(--step-color-primary) 60%, transparent);

  /* ✅ card stays white; only the header stripe gets the blue */
  background: var(--ui-surface);
  border-color: var(--featured-stroke-color);
  box-shadow: var(--featured-stroke-glow);
}

.step-card:not(.is-open) .step-header{
  /* no background here; collapsed is handled above already */
  color: var(--md-sys-color-on-surface);
  border-bottom: 1px solid var(--ui-stroke);
}

/* Panel body (the content region) */
.step-card [data-step-panel]{
  background: var(--ui-surface-variant);
  color: var(--md-sys-color-on-surface);
}

/* Hover/focus feedback (matches your global glow) */
.step-card .step-header:hover{
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}
.step-card .step-header:focus-visible{
  border-color: var(--ui-stroke-hover);
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--focus-glow-blur) var(--focus-ring-color);
}

/* Tinted placeholder text (Ascend-owned cosmetics) */
.card--fill text.placeholder {
  fill: var(--ascend-caption-placeholder-fill, rgb(3, 162, 171));
}

/* Closed accordion buttons: navy stroke */
#stepper > div:not(.is-open) .step-header-wrap,
#stepper > div[data-step="caption"]:not(.is-open) > .step-header{
  background: var(--ui-surface); /* ✅ load state = white/light */
  border: 1px solid color-mix(in oklab, var(--md-sys-color-on-surface) 22%, transparent); /* ✅ darker/crisper */
  border-radius: var(--phone-radius);

  /* ✅ kill the fuzzy “double stroke” */
  box-shadow: 0 1px 0 rgba(0,0,0,.06);

  min-height: 3.4rem;
  display: flex;
  align-items: center;
}

/* Buttons — CANONICAL */
.ecc-btn {
  inline-size: 1.75rem;
  block-size: 1.75rem;

  /* shape + sizing */
  border-radius: 50% !important;
  aspect-ratio: 1 / 1;
  padding: 0;

  /* layout */
  display: inline-flex;
  align-items: center;
  justify-content: center;

  /* visuals (Ascend controls) */
  background: var(--ascend-control-bg, #ffffff);
  border: 1px solid var(--ascend-control-border, rgba(148, 163, 184, 0.85));
  color: var(--ascend-app-text-main, #020617);
  text-decoration: none !important;

  /* type + motion */
  font: 600 0.85rem/1 var(--font-family, system-ui);
  transition:
    box-shadow var(--motion-duration-1) var(--motion-ease),
    background-color var(--motion-duration-1) var(--motion-ease),
    transform var(--motion-duration-1) var(--motion-ease);
}

/* Buttons — pressed (canonical, token-based) */
.ecc-btn[aria-pressed="true"] {
  outline: none; /* avoid default rectangular outline */
  background: var(--ascend-control-bg-active, #eef2f7);
  color: var(--md-sys-color-primary);
  border-color: var(--ascend-control-border, rgba(15, 23, 42, 0.10));
  /* thin, token-based ring so it matches Ascend focus visuals */
  box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

/* Optional: keyboard-only ring, consistent with your body.kbd focus policy */
body.kbd .ecc-btn[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--focus-ring-color);
}

/* Remove any inherited text underline on the label */
.ecc-btn,
.ecc-btn:focus,
.ecc-btn:hover {
  text-decoration: none;
}

.ecc-btn:hover, .ecc-btn:focus-visible { background: var(--ascend-control-bg-hover, #f8fafc); outline: none; }
.ecc-btn:hover { transform: translateY(-1px); }

/* Mobile tweaks */
@media (max-width: 640px) {
  .step-card[data-step="mechanicals"]:not(.is-open) .step-header { padding-bottom: 1rem; }
}

/* Make header wraps true edge-to-edge slabs (Design/Mechanicals/Finish) */
.step-header-wrap{
  position: relative;
  display: flex;
  align-items: center;
  gap: .5rem;

  /* slab geometry */
  width: 100%;
  margin: 0;

  /* ✅ canonical horizontal inset for ALL headers */
  padding-inline: 1.25rem;
}

/* ✅ Caption must match the same inset, always */
.step-card[data-step="caption"] .step-header-wrap{
  padding-inline: 1.25rem;
}

/* Keep the existing mechanials selector for specificity parity */
.step-card[data-step="mechanicals"] .step-header-wrap {
  position: relative;
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* Let the title take the left, pill pushes to the right */
.step-card[data-step="mechanicals"] .step-header-wrap [data-step-toggle] {
  flex: 1 1 auto;
  padding-right: 0; /* overrides earlier padding-right safely */
}

/* Place the pill inline at the right (no absolute positioning) */
.step-card[data-step="mechanicals"] .step-header-wrap #eccPill.ecc-pill {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--density-gap);
  margin-left: auto;
  padding-right: 0; /* ✅ header-wrap owns the inset */
}

/* Remove underline and focus outline in all states */
.ecc-btn:hover,
.ecc-btn:focus,
.ecc-btn:active {
  text-decoration: none !important;
  outline: none;
}

/* Design (open): unified stripe, full-bleed to card edge */
.step-card[data-step="design"].is-open .step-header-wrap{
  background: var(--step-header-open-bg);
  border-bottom: 0 !important;
  position: relative;

  /* harden full-bleed geometry */
  margin: 0;
  width: 100%;

  /* ✅ match closed indentation */
  padding-inline: 1.25rem;
}

/* Caption has NO .step-header-wrap — tint the button itself when open */
.step-card[data-step="caption"].is-open > .step-header{
  background: var(--step-header-open-bg) !important;
  border-bottom: var(--featured-stroke-width) solid var(--featured-stroke-color);
  backdrop-filter: saturate(1.1) blur(6px);
  min-height: 3.4rem;
  border-radius: var(--phone-radius) var(--phone-radius) 0 0;
  padding-inline: 1.25rem;
}

/* Design uses the wrap slab, not the button */
.step-card[data-step="design"].is-open .step-header{ background: transparent !important; border-bottom: 0 !important; }
.step-card[data-step="design"].is-open .step-header-wrap::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:var(--ui-stroke); pointer-events:none;
}
.step-card[data-step="design"] #fontPill{ display:flex !important; }

/* Pills: hide when their flipper is not active */
.step-card[data-step="design"]:not(.is-open) #fontPill,
.step-card[data-step="mechanicals"]:not(.is-open) #eccPill{
  visibility: hidden;
  pointer-events: none;
}

.step-card[data-step="design"].is-open #fontPill,
.step-card[data-step="mechanicals"].is-open #eccPill{
  visibility: visible;
  pointer-events: auto;
}

.step-card[data-step="design"] .step-header-wrap #fontPill.ecc-pill{
  align-items:center;
  flex-wrap:nowrap;
  gap:var(--density-gap);
  margin-left:auto;
}

/* Font pill alignment */
.step-card[data-step="design"] .step-header-wrap{
  display:flex;                    /* mirror Mechanicals */
  align-items:center;              /* vertical centering */
  gap:.5rem;
}

/* Let the title take the left; pill pushes right (mirrors [data-step-toggle] rule) */
.step-card[data-step="design"] .step-header-wrap [data-step-toggle]{
  flex:1 1 auto;
  padding-right:0;
}

/* =========================
   4. CONTROLS (inputs/selects/Menu)
========================= */

/* CODEDESK header mark (contrast + crisp) */
.codedesk-mark a{
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
}
.codedesk-mark a:hover{ text-decoration: underline; }

input[type="text"],
input[type="email"],
input[type="url"],
input[type="number"],
input[type="search"],
input[type="password"],
input[type="color"],
select{
  background: var(--ui-surface-variant);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-md);
  height: var(--density-control-h);
  box-shadow: 0 0 0 1px var(--ui-stroke) inset;  /* thin baseline */
  transition:
    box-shadow var(--motion-duration-1) var(--motion-ease),
    border-color var(--motion-duration-1) var(--motion-ease),
    color var(--motion-duration-1) var(--motion-ease),
    background-color var(--motion-duration-1) var(--motion-ease);
}

input:hover,
textarea:hover,
select:hover{
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}


/* Muted/disabled helper */
.field-muted,
.field-muted *{
  opacity:.55;
  pointer-events:none;
}

/* Finish mode must keep the export sparkle clickable */
#stepper.finish-active #exportBtn{
  pointer-events:auto !important;
  opacity: 1 !important;

  /* Match header pills (icon-only circle) */
  inline-size: 1.75rem;
  block-size: 1.75rem;
  border-radius: 999px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  background: var(--ascend-control-bg, #ffffff);
  border: 1px solid var(--ascend-control-border, rgba(148, 163, 184, 0.85));
  color: var(--ascend-app-text-main, #020617);
  font: 600 0.85rem/1 var(--font-family, system-ui);
}

/* === TOP BAR — text styling (only) =================================== */
/* Restore heavier label for the pills and keep baselines consistent */
#qrType{
  font: 600 var(--typo-input-size)/1 var(--font-family);
  letter-spacing: .01em;
  color: var(--md-sys-color-on-surface);
}

/* === TOP BAR — pill layout =========================================== */
#qrType{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  line-height: 1;             /* prevent extra vertical space from fonts */
  padding-inline: 1rem;       /* horizontal padding stays constant */
}

/* Safari/WebKit quirk: ensure the selected option uses the same weight */
#qrType option { font-weight: 600; }

/* Unified top-bar controls (selects + Menu) */
.control,
#appMenuBtn,
#qrType,
select.rounded-md,
.topctl{
  background: var(--ui-surface);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-md);
  /* BASELINE: thin inset stroke only */
  box-shadow: 0 0 0 1px var(--ui-stroke) inset;
  height: var(--density-control-h);
  transition:
    box-shadow var(--motion-duration-1) var(--motion-ease),
    border-color var(--motion-duration-1) var(--motion-ease);
}

#fontPill select {
  display: inline-flex;
  align-items: center;          /* vertical centering */
  justify-content: center;      /* horizontal centering */
  text-align: center;
  line-height: 1;               /* eliminate font baseline drift */
  height: var(--density-control-h);
  padding-inline: 1rem;
}

/* Make top-bar controls feel like .ecc-btn on hover/focus/active */
.topctl:hover,
#qrType:hover,
#appMenuBtn:hover,
.topctl:focus-visible,
#qrType:focus-visible,
#appMenuBtn:focus-visible{
  background: var(--ascend-control-hover-wash, rgba(255,255,255,.08));
  transform: translateY(-1px);
  outline: none;
}

/* Active/click state parity with your focus ring tokens */
.topctl:active,
#qrType:active,
#appMenuBtn:active{
  transform: translateY(0);
  box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
  border-color: var(--md-sys-color-primary);
}

/* Emoji picker buttons */
#emojiGrid button{
  background: var(--ui-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-sm);
  box-shadow: 0 0 0 1px var(--ui-stroke) inset;

  /* emoji = square glyph buttons, not form controls */
  width: 2.25rem;
  height: 2.25rem;
  display: inline-grid;
  place-items: center;
  font-size: 1.25rem;
  line-height: 1;
  padding: 0;
}

#emojiGrid button:hover{
  box-shadow: 0 0 0 1px var(--ui-stroke-hover) inset;
}

/* HOVER: keep thin inset + add faint outer glow */
.control:hover,
#appMenuBtn:hover,
select.rounded-md:hover,
.topctl:hover{
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}

/* Hide all focus by default (mouse/touch or scripted focus) */
:focus { outline: none; }

/* Show the ring only when the user is tabbing (keyboard) */
body.kbd .control:focus-visible,
body.kbd #appMenuBtn:focus-visible,
body.kbd select.rounded-md:focus-visible,
body.kbd .topctl:focus-visible,
body.kbd button[data-emoji-target]:focus-visible,
body.kbd input:focus-visible,
body.kbd textarea:focus-visible,
body.kbd select:focus-visible{
  outline: none;
  border-color: var(--ui-stroke-hover);
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--focus-glow-blur) var(--focus-ring-color);
}

/* Remove native arrow so our chevron matches */
select.rounded-md,
select.topctl{
  -webkit-appearance:none;
  appearance:none;
  padding-right:2rem;
}
button.topctl{ padding-right:2rem; }

/* Optional: ensure consistent min-width so short labels (like “M”) don’t look cramped */
#ecc{ min-width: 3.25rem; justify-content:center; }

/* Chevron for top controls */
.topctl--chev{ position: relative; }

.topctl--chev::after{
  content:"";
  pointer-events:none;
  position:absolute;
  right:.6rem;
  top:50%;
  width:.75rem;
  height:.75rem;
  transform:translateY(-50%);
  opacity:.85;
  background-repeat:no-repeat;
  background-position:center;
  background-size:100% 100%;
  background-image: var(--chev-icon);
}

/* Emoji picker trigger = match other controls */
button[data-emoji-target]{
  /* visuals */
  background: var(--ui-surface);
  color: var(--md-sys-color-on-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-md);
    box-shadow: 0 0 0 1px var(--ui-stroke) inset;

  /* sizing / type */
  height: var(--density-control-h);
  padding: 0 .875rem;
  line-height: 1;
  font-size: .875rem;
  font-weight: 600;

  /* behavior */
  cursor: pointer;
  transition:
    box-shadow var(--motion-duration-1) var(--motion-ease),
    border-color var(--motion-duration-1) var(--motion-ease);
}

button[data-emoji-target]:hover{
  box-shadow: 0 0 0 1px var(--ui-stroke-hover) inset, var(--elevation-2);
}

#emojiGrid button:focus{
  outline: none;
  border-color: var(--ui-stroke-hover);
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--focus-glow-blur) var(--focus-ring-color);
}

/* If it was getting a white default button style anywhere, neutralize it */
button[data-emoji-target]::-moz-focus-inner{ border: 0; }

/* DISPLAY: section headers (Caption / Design / Mechanicals / Finish) */
.step-header{
  font-family: var(--font-family);
  font-size: var(--typo-display-size, 1rem);
  font-weight: var(--typo-display-weight, 700);
  letter-spacing: var(--typo-display-track, .01em);
  color: var(--md-sys-color-on-surface);

  /* horizontal padding lives on .step-header-wrap */
  padding: 0;

  background: transparent;
  border: 0;
  box-shadow: none;
  border-radius: 0;

  width: 100%;
  display: flex;
  align-items: center;
  min-height: 3.4rem; /* matches your updated value */
}

.step-card[data-step="caption"] [data-step-panel]{
  padding-left: 1.25rem !important;
  padding-right: 1.25rem !important;
}

/* ✅ Caption step does NOT use .step-header-wrap in the HTML.
   So: treat the .step-header itself as the header slab. */

/* Caption — parity with other steps (stowed stroke + open header slab) */
.step-card[data-step="caption"]{
  /* dedicated closed-stroke token (never “disappears”) */
  --stepper-stroke-closed: var(--md-sys-color-outline, rgba(15, 23, 42, 0.22));

  border: 1px solid var(--stepper-stroke-closed);
  border-radius: var(--phone-radius);
  background: var(--ui-surface);
  overflow: hidden;

  /* reinforce the edge even when the border blends into the page */
  box-shadow: 0 0 0 1px var(--stepper-stroke-closed) inset;
}

/* Closed: subtle tint + crisp edge */
#stepper > .step-card[data-step="caption"]:not(.is-open) .step-header{
  background: color-mix(in oklab, var(--ui-surface) 92%, var(--step-color-primary) 8%);
  border-bottom: 1px solid var(--stepper-stroke-closed);
  box-shadow:
    0 0 0 1px var(--stepper-stroke-closed) inset,
    0 1px 0 rgba(0,0,0,.06);
}

/* Caption header padding (since there is no .step-header-wrap) */
.step-card[data-step="caption"] .step-header{
  padding-left: 1.25rem !important;
  padding-right: 1.25rem !important;
}

/* CLOSED: the header IS the pill — keep full rounding */
#stepper > .step-card[data-step="caption"]:not(.is-open) > .step-header{
  border-radius: var(--phone-radius) !important;
}

/* OPEN: header becomes the slab — round only the top corners */
#stepper > .step-card[data-step="caption"].is-open > .step-header{
  border-radius: var(--phone-radius) var(--phone-radius) 0 0 !important;
}

/* Open: header slab styling (applied to .step-header directly) */
#stepper .step-card[data-step="caption"].is-open .step-header{
  background: var(--step-header-open-bg);
  backdrop-filter: saturate(1.1) blur(6px);
  border-bottom: 0 !important; /* we paint the rule via ::after for parity */
  min-height: 3.4rem;
  border-radius: var(--phone-radius) var(--phone-radius) 0 0;
  position: relative;
}

/* Open: single thin rule at bottom of header slab */
#stepper .step-card[data-step="caption"].is-open .step-header::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background: var(--ui-stroke);
  pointer-events:none;
}

/* Open: tuck the panel under the header rule (no step) */
#stepper .step-card[data-step="caption"].is-open [data-step-panel]{
  margin-top: -1px;
  background: var(--ui-surface-variant);
}

.step-header .title{
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  color: inherit;
  display: block;
  padding: 0; /* ✅ padding now lives on .step-header so Caption matches */
}

/* LABELS: field labels like “Module Fill”, “Background” */
label,
.field-label{
  font-family: var(--font-family);
  font-size: var(--typo-label-size);
  font-weight: var(--typo-label-weight);
  letter-spacing: var(--typo-label-track);
  color: var(--typo-label-color);
}

/* INPUT TEXT: value text inside inputs/selects/buttons */
input, textarea, select,
.control, .topctl, button[data-emoji-target]{
  font-family: var(--font-family);
  font-size: var(--typo-input-size);
  font-weight: var(--typo-input-weight);
}

/* PLACEHOLDERS: “dummy” text in fields */
input::placeholder,
textarea::placeholder{
  color: var(--typo-ph-color);
  font-weight: var(--typo-ph-weight);
  opacity: var(--typo-ph-opacity);
}

/* Utility: “temp” or dummy inline text outside inputs */
.text-temp {
  color: var(--typo-ph-color);
  font-weight: var(--typo-ph-weight);
  opacity: var(--typo-ph-opacity);
  font-style: italic;
}

/* default: no transitions before JS marks ready */
:not(.ui-ready) #stepper .step-header,
:not(.ui-ready) #stepper > .step-card{
  transition: none !important;
  box-shadow: none !important;
}

/* Design & Mechanicals: scroll inside a viewport-based cap that clears the footer */
.step-card[data-step="design"].is-open [data-step-panel],
.step-card[data-step="mechanicals"].is-open [data-step-panel]{
  overflow: auto;
  max-height: calc(
    100dvh
    - var(--header-h,56px)   /* top controls if present */
    - 24px                   /* card margins/breathing */
  );
  overscroll-behavior: contain;
  scrollbar-gutter: stable both-edges;
  scrollbar-width: thin;
  scrollbar-color: var(--ui-stroke-hover) transparent;
}

/* Mechanicals: no internal scroller; let #stepper scroll instead */
.step-card[data-step="mechanicals"].is-open [data-step-panel]{
  overflow: visible !important;
  max-height: none !important;
  overscroll-behavior: auto;       /* release containment */
  scrollbar-gutter: auto;
  scrollbar-width: none;           /* hide any vestigial bar in Firefox */
}
.step-card[data-step="mechanicals"].is-open [data-step-panel]::-webkit-scrollbar { display: none; }

/* Base pill styles (authoritative) */
.step-card[data-step="mechanicals"] .step-header-wrap #eccPill.ecc-pill {
  display: inline-flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--density-gap);
  margin-left: auto;
}

/* Stowed vs open: never remove from layout (prevents “gone” states) */
.step-card[data-step="mechanicals"]:not(.is-open) #eccPill{
  visibility: hidden;                   /* keeps header geometry stable */
  pointer-events: none;
}

.step-card[data-step="mechanicals"].is-open #eccPill{
  visibility: visible;
  pointer-events: auto;
}

/* Kill any competing header paint so the wrap shows through */
.step-card[data-step="mechanicals"].is-open .step-header {
  background: transparent !important;  /* beats #stepper>div.is-open .step-header */
  border-bottom: 0;
}

#emojiSearch { display: none !important; }

/* There should be no "Details" step in CodeDesk */
.step-card[data-step="details"]{
  display: none !important;
}

/* =========================
   5. PREVIEW LAYOUT
========================= */

/* -----------------------------------------------------------------------
   QR PREVIEW CARD — single geometry; stroke (OFF) vs gradient fill (ON)
   ----------------------------------------------------------------------- */
#qrPreview{
  position: relative;
  border-radius: var(--phone-radius);
  overflow: clip;                      /* clip to the rounded card */
  background: transparent !important;  /* no card fill here */
  border: 0 !important; 
  box-shadow: none !important; 
  isolation: isolate;                  /* local stacking; ::before stays behind */
}

/* One pseudo-element draws BOTH modes so size/shape never drift */
#qrPreview::before{
  content:"";
  position:absolute;
  z-index: 0;
  inset:0;                  /* exact same box in both modes */
  border-radius:inherit;
  pointer-events:none;
}

/* Background ON = gradient fill (set via --bg-fill) */
#qrPreview.card--fill::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  background: var(--bg-paint, #fff);   /* solid or gradient from JS */
  opacity: var(--bg-alpha, 1);         /* 🔑 hook your slider sets */
  box-shadow:none;
  pointer-events:none;
  z-index:0;                           /* behind QR + caption */
}

/* Background OFF = empty bright turquoise stroke */
#qrPreview.card--stroke::before{
  inset:0;
  border-radius:inherit;
  background: transparent;
  opacity: 1; /* ensure stroke stays visible even if card--fill leaves --bg-alpha at 0 */
  box-shadow:none;
  border: var(--stage-frame-w, 3px) solid var(--stage-frame, #1ff0ff);
}

/* Portrait stage wrapper (outer container) */
.preview-stage{
  position: relative;
  background: transparent !important;
  width: clamp(250px, 26vw, 330px);
  aspect-ratio: .63 / 1;   /* wallet portrait */
  margin-inline: auto;
  border-radius: var(--phone-radius);
  display: grid;
  align-items: start;
  justify-items: center;
  overflow: visible;
  padding: 0;
}

/* Square state when there is no caption */
.preview-stage.preview--square{
  width: clamp(250px, 26vw, 330px);
  aspect-ratio: 1 / 1;        /* true square shell */
  align-items: start;          /* top-anchor like wallet mode */
}

/* QR background paint layer (real element for better browser support) */
#qrBgPaint{
  position: absolute;
  inset: 0;
  z-index: 0;                         /* behind the QR mount */
  border-radius: inherit;
  pointer-events: none;
  background: #ffffff;                /* default white, JS will update */
}

/* QR mount = container for the SVG */
#qrMount{
  position: relative;
  z-index: 1;                         /* above the background paint layer */
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: inherit;
  overflow: clip;
  background: transparent !important; /* never add a host fill */
}

/* Circular color tiles: add a visible ring around the CIRCLE (not the cell) */
input[type="color"].color-dot{
  -webkit-appearance: none;
  appearance: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 9999px;
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--ascend-app-text-main) 18%, transparent);
}

input[type="color"].color-dot::-webkit-color-swatch-wrapper{
  padding: 0;
  border-radius: 9999px;
}
input[type="color"].color-dot::-webkit-color-swatch{
  border: 0;
  border-radius: 9999px;
}
input[type="color"].color-dot::-moz-color-swatch{
  border: 0;
  border-radius: 9999px;
}

#qrMount > svg{
  display: block;
  width: 100%;
  height: auto;
  border-radius: inherit;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important; /* no bg rects from generators */
}

  .preview-stage,
  #qrPreview,
  #prevSubtype,
  #nextSubtype { z-index: 1; }

  /* Let the stepper slide under the preview */
  #stepper {
    position: relative;
    z-index: 1;                       /* below the raised preview section */
  }

/* Finish: header-only row; let it flow like others */
.step-card[data-step="finish"]{
  position: static !important;
  bottom: auto !important;
  z-index: auto !important;
  backdrop-filter: none !important;
  border-top: 1px solid var(--ui-stroke);
}

/* Finish header row should look like the other header slabs */
.step-card[data-step="finish"] .step-header-wrap{
  background: color-mix(in oklab, var(--ui-surface) 92%, var(--step-color-primary) 8%);
  border-bottom: 1px solid var(--stepper-stroke-closed);
  box-shadow:
    0 0 0 1px var(--stepper-stroke-closed) inset,
    0 1px 0 rgba(0,0,0,.06);
}

/* When finish card is "open" (if JS ever adds .is-open), use the open slab */
.step-card[data-step="finish"].is-open .step-header-wrap{
  background: var(--step-header-open-bg);
}

/* …but keep the on-phone UI (arrows) interactive */
.preview-stage .nav-arrow {
  pointer-events: auto;
  z-index: 50;            /* ↑ ensure above sticky + stepper */
  position: absolute;
}

/* Make the WHOLE sticky preview block "glass" on mobile/stacked */
@media (max-width: 1279px){
  /* Make only the phone preview "glass" on mobile; never mute the stepper controls */
  .preview-stage,
  .preview-stage > .absolute,
  #qrPreview,
  #qrMount,
  #qrMount > svg { pointer-events: none !important; }

  /* …but keep the L/R arrows on the phone clickable */
  .preview-stage .nav-arrow {
    pointer-events: auto !important;
  }
}

/* =========================
   6. ARROWS
========================= */
.nav-arrow{
  background: var(--ui-surface);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-full);
  box-shadow: 0 0 0 1px var(--ui-stroke) inset; /* thin baseline */
}
.nav-arrow:hover{
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}
.nav-arrow:focus{
  outline: none;
  border-color: var(--ui-stroke-hover);
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--focus-glow-blur) var(--focus-ring-color);
}

/* Triangle glyphs */
#prevSubtype::after,
#nextSubtype::after{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
}
#prevSubtype::after{
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 10px solid var(--md-sys-color-on-surface);
}
#nextSubtype::after{
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 10px solid var(--md-sys-color-on-surface);
}  

/* Put each arrow just outside the card edges */
#prevSubtype{
  top:50%;
  left: calc(-2 * var(--edge-gutter));        /* or: calc(-1 * var(--edge-gutter)) */
  right: auto;
  transform: translateY(-50%);
  z-index: 20;
}
#nextSubtype{
  top:50%;
  right: calc(-2 * var(--edge-gutter));       /* or: calc(-1 * var(--edge-gutter)) */
  left:  auto;
  transform: translateY(-50%);
  z-index: 20;
}

/* High-contrast toggle (add .hc on <html>) */

html.hc, :root.hc{
  --md-sys-color-on-surface: #fff;
  --md-sys-color-outline: rgba(255,255,255,.65);
  --md-sys-color-outline-variant: rgba(255,255,255,.9);
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce){
  :root{ --motion-scale: .01; }
}

/* Optional hover/focus feedback (subtle glow) */
input[type="color"]:hover{
  filter: drop-shadow(0 0 4px var(--ui-stroke-hover));
}
input[type="color"]:focus{
  outline: none;
  filter: drop-shadow(0 0 6px var(--focus-ring-color));
}

/* Group color pickers + hex fields neatly */
.color-field {
  display: flex;
  align-items: center;
  gap: var(--density-gap);
}

/* Make hex field visually tied to its picker */
.color-field input[type="text"] {
  flex: 1;
  text-align: center;
  font-family: monospace;
  font-size: .875rem;
  font-weight: 500;
  color: var(--md-sys-color-on-surface);
  background: var(--ui-surface-variant);
  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-md);
  height: var(--density-control-h);
  box-shadow: 0 0 0 1px var(--ui-stroke) inset;
  transition:
    box-shadow var(--motion-duration-1) var(--motion-ease),
    border-color var(--motion-duration-1) var(--motion-ease);
}

.color-field input[type="text"]:hover {
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}

.color-field input[type="text"]:focus {
  outline: none;
  border-color: var(--ui-stroke-hover);
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--focus-glow-blur) var(--focus-ring-color);
}

/* Color chip: fixed, perfect circle — never stretch */
input[type="color"]{
  width: 1.75rem;
  height: 1.75rem;
  min-width: 1.75rem;       /* prevent flex/grid shrinking */
  min-height: 1.75rem;
  aspect-ratio: 1 / 1;      /* stay square even if a parent tries to stretch */
  flex: 0 0 1.75rem;        /* don’t grow or shrink */
  align-self: center;       /* keeps it centered in tall rows */
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
          appearance: none;
  box-sizing: content-box;
}

/* Make the actual swatch inherit shape and remove its inner border */
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; border-radius: 50% }
input[type="color"]::-webkit-color-swatch { border: none; border-radius: 50% }
input[type="color"]::-moz-color-swatch { border: none; border-radius: 50% }

/* ---- Color rows: keep chip circular and let the hex input take the width ---- */

/* Generic label rows: title + control */
label.text-sm.block{
  display: grid;
  grid-template-columns: auto 1fr;   /* title, then a flexible control */
  align-items: center;
  gap: .75rem;
}

/* Rows that include a color swatch: title · swatch · hex */
.step-card[data-step="design"] label:has(input[type="color"]),
.step-card[data-step="mechanicals"] label:has(input[type="color"]){
  grid-template-columns: auto auto 1fr; /* title, chip, hex input */
}

/* Make the hex field actually flex and not collapse */
.step-card[data-step="design"] label:has(input[type="color"]) input[type="text"],
.step-card[data-step="mechanicals"] label:has(input[type="color"]) input[type="text"]{
  width: 100%;
  min-width: 16ch;     /* keep it readable on tight layouts */
}

/* Optional: keep the chip from crowding the field */
.step-card[data-step="design"] label:has(input[type="color"]) input[type="color"],
.step-card[data-step="mechanicals"] label:has(input[type="color"]) input[type="color"]{
  margin-inline-start: .25rem;
}

/* === Modal & legacy dropdown overrides (safe, CSS-only) ================== */

/* 2) Bulletproof centering of the dialog card (ignores any old absolute rules) */
#appModal > div,
#emojiModal > div {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
}

/* === Modal overlays (final, consolidated) =============================== */

/* Hide any legacy dropdown if it still exists */
#appMenu { display: none !important; }

/* Prevent locked state when hidden */
#appModal.hidden,
#emojiModal.hidden {
  display: none !important;
}

/* Neutralize legacy popover positioning inside overlays */
#appModal [role="menu"],
#emojiModal [role="menu"] {
  position: static !important;
}

/* Backdrop polish + allow dismissal clicks */
.modal-bg {
  /* ✅ light modal backdrop (no dark theme vibes) */
  background: rgba(255,255,255,.70);
  backdrop-filter: blur(var(--ascend-modal-blur, 3px));
  pointer-events: auto;
}

/* ✅ force emoji dialog to light, even if any dark classes exist */
#emojiModal > div{
  background: #fff !important;
  color: #0b0b0b !important;
  border: 1px solid rgba(15, 23, 42, .18) !important;
}

/* ✅ make the emoji picker a real, full-width grid */
#emojiGrid{
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(2.25rem, 1fr)) !important;
  gap: .5rem !important;
  width: 100% !important;
}

/* When hidden, backdrop ignores all input */
#appModal.hidden .modal-bg,
#emojiModal.hidden .modal-bg {
  pointer-events: none;
}

/* === QR Types: show the custom chevron === */
#qrType {
  -webkit-appearance: none;
          appearance: none;
  padding-right: 2rem;                       /* room for chevron */
  background-image: var(--chev-icon);        /* your SVG variable */
  background-repeat: no-repeat;
  background-position: right .65rem center;  /* nudge as before */
  background-size: .75rem .75rem;
}

/* Types Hover for Pills (shared) */
#qrType:hover {
  box-shadow:
    0 0 0 1px var(--ui-stroke-hover) inset,
    0 0 var(--hover-glow-blur) var(--hover-glow-color);
}

/* === Hamburger: no chevron; keep icon centered ======================== */
#appMenuBtn::after { content: none !important; }
#appMenuBtn {
  padding-inline: 1rem;               /* same side padding as QR Types */
}


/* =========================
  MOBILE OVERRIDES
========================= */

/* --- Single-column / stacked behavior (< 1280px) -------------------- */
@media (max-width: 1279px) {
  /* Only the *first* stage-stick (the preview section) is sticky */
  main > section.stage-stick:first-of-type {
    position: sticky;
    top: calc(var(--header-h, 56px) + 8px);
    z-index: 30;
  }

  /* Let the stepper flow normally (no fixed footer) */
  #stepper{
  position: static;
  height: auto;
  min-height: 0;
  overflow: visible;
  padding-bottom: 96px; /* keep a little breathing room */
  margin-bottom: 16px;
}

  /* No fixed footer spacing needed */
  main{
    padding-bottom: 0;
  }
  
  /* Ensure the stepper is not sticky in stacked mode */
  #stepper.stage-stick {
    position: static;
    top: auto;
  }
}

  /* Park the stepper up under the phone */
@media (max-width: 1279px){
  :root{
  /* how far the stepper is allowed to slide under the phone */
  --preview-overlap: clamp(180px, 52vh, 320px);
  --preview-gap: 12px;
  --park-nudge: 16px;
}

  #stepper{
    margin-top: calc(var(--preview-overlap) * -1);
    padding-top: calc(var(--preview-overlap) + var(--preview-gap));
    scroll-padding-top: calc(var(--header-h, 56px) + var(--park-offset, 180px));
    scroll-behavior: smooth;
  }

   #stepper .step-header{
    scroll-margin-top: calc(var(--header-h, 56px) + var(--park-offset, 180px));
  }
}

 /* Desktop align fix */
@media (min-width: 1280px){
  .stage-stick { position: static; top: auto; }

  /* Standard scroll: #stepper does not own scrolling on desktop. */
  #stepper{
    height: auto;
    overflow: visible;
    margin-top: 0;
    padding-top: 0;
  }
}

@media (max-width: 1279px){
  html { scroll-padding-top: calc(var(--header-h,56px) + var(--park-offset,180px)); }
}

 /* === Emoji modal: always on top, full-viewport ======================= */
 #emojiModal {
    position: fixed;
    inset: 0;
    z-index: 2147483647;           /* win against any local stacking ctx */
    display: grid;                 /* center its panel if you have one */
    place-items: center;
}
#emojiModal.hidden { display: none; }

/* While the emoji modal is open, make everything under the phone ignore taps */
:root.emoji-open .preview-stage,
:root.emoji-open #qrPreview {
  pointer-events: none !important;
}
:root.emoji-open #emojiModal {
  pointer-events: auto !important; /* but keep the modal interactive */
}

/* Step parking: every step header parks under the phone cleanly */
.step-card .step-header {
  scroll-margin-top: calc(var(--header-h, 56px) + var(--park-offset, 180px));
}

/* Stack the "Show caption" toggle below the text field */
.step-card[data-step="caption"] .step-body {
  display: flex;
  flex-direction: column;   /* stack instead of row */
  align-items: flex-start;  /* left-align the checkbox label */
  gap: 0.5rem;              /* small vertical space */
}

/* --- Global Modal Priority Layer --- */
.modal-bg,
[id$="Modal"] {
  position: fixed !important;
  inset: 0 !important;
  z-index: 9999 !important; /* ensure it's above all sticky and preview layers */
  pointer-events: auto !important;
}

/* ------------------------------------------------------------
   Background controls: branded link + clean color tiles + blue sliders
------------------------------------------------------------ */

/* No squares around circular color tiles (override any utility borders) */
input[type="color"] {
  border: none !important;
  box-shadow: none !important;
  background: transparent !important;
  border-radius: 9999px !important;
  padding: 0 !important;
  width: 1.75rem !important;
  height: 1.75rem !important;
  cursor: pointer;
}
input[type="color"]::-webkit-color-swatch-wrapper {
  padding: 0 !important;
  border: none !important;
  border-radius: 9999px !important;
}
input[type="color"]::-webkit-color-swatch {
  border: none !important;
  border-radius: 9999px !important;
}

/* Ascend-blue sliders */
input[type="range"] {
  accent-color: var(--ascend-app-accent) !important;
}

/* Branded link button */
#bgLink {
  width: 2.25rem;
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  border-radius: 0.75rem;
  border: 1px solid var(--ascend-app-border);
  background: var(--ascend-app-surface);
  box-shadow: 0 1px 0 rgba(0,0,0,0.04);

  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  user-select: none;
}
#bgLink:hover {
  background: color-mix(in oklab, var(--ascend-app-surface), var(--ascend-app-accent) 6%);
}
#bgLink:active {
  transform: translateY(1px);
}

/* CodeDesk — Mandatory filename capture (under preview) */
#codedeskFilenameSection{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  margin-top: 12px;
}

#codedeskFilenameSection > label{
  display: block;
  width: min(360px, calc(100% - 24px));
  margin: 0 auto;
}

/* Make the field read as a real, opaque input */
#codedeskFilename{
  appearance: none;
  width: 100%;
  height: var(--density-control-h);
  line-height: var(--density-control-h);
  padding: 0 12px;
  box-sizing: border-box;

  background: var(--md-sys-color-surface); /* more opaque than surface-variant */
  color: var(--md-sys-color-on-surface);

  border: 1px solid var(--ui-stroke);
  border-radius: var(--shape-corner-md);

  box-shadow: 0 0 0 1px var(--ui-stroke) inset, var(--elevation-1);
}

#codedeskFilename::placeholder{
  opacity: .65;
}

#codedeskFilename:focus{
  outline: none;
  border-color: var(--ascend-app-accent, var(--ui-focus-ring));
  box-shadow:
    0 0 0 1px var(--ascend-app-accent, var(--ui-focus-ring)) inset,
    0 0 0 3px color-mix(in oklab, var(--ascend-app-accent, var(--ui-focus-ring)) 22%, transparent);
}

/* Emoji picker should own its layout */
#emojiModal emoji-picker{
  max-height: none !important;
  height: auto !important;
}