/* ================================================================
   S3XY CARDS — create-v2.css
   The look of /create/ (choose a card, design it, options, details,
   review and pay). Loaded after engraving.css, eng-motion.css and
   create-page.css, which are shared with /order/ and /admin/ and are
   not edited: everything this page changes is in this file.

   Those stylesheets build their components on a small set of custom
   properties (--ink, --surface, --gray-5, --hair, --silver, ...).
   Section 1 points every one of them at the storefront's values, so
   the three parts of the site read as one. The rest overrides what
   the properties cannot reach, and holds the flow's own components.
   The shared numbers (radii 12 / 18 / 28, 52px controls, the 2px
   white focus ring, the white ring and tick of a chosen option) are
   those of spec\components.md. site-v2.css is never loaded here.

   No layout dimension the editor's script measures is changed:
   .ed-stage keeps padding 0, and the card keeps its 1013 x 638 shape.

   ------------------------------------------------------------
    1. Tokens
    2. Page
    3. Focus
    4. The flow header
    5. Step dots
    6. Buttons
    7. Fields, tick boxes, small labels
    8. The card on the stage
    9. Dock, tabs, tiles, tray, tip
   10. Review hero, preview stage
   11. Messages
   12. Reduced motion
   25-40. Layout: header, editor shell, panels, bottom bar
   41. The flow's own components: chooser, option cards, swatches,
       price lines, link field, brief, agreements, bottom bar, price sheet
   42. Steps on a wide screen
   43. Phones
   44. Dialogs, sheets, toast
   45. Loading and empty states
   ================================================================ */

/* ============================================================
   1. TOKENS
   The names are the ones engraving.css and create-page.css use;
   the values are the storefront's (site-v2.css :root).
   ============================================================ */
:root{
  /* the accent: one block, the same five values in site-v2.css, chrome.css and app-v2.css.
     It marks the current step dot, progress, eyebrows and small icons. Never a choice, focus, a price or a button. */
  --accent:#FF2D55; --accent-strong:#E80038; --on-accent:#FFFFFF;
  --accent-text:#FF5C7A; --accent-glow:rgba(255,45,85,.35);
  /* amber:
  --accent:#FFB547; --accent-strong:#FFB547; --on-accent:#09090B;
  --accent-text:#FFB547; --accent-glow:rgba(255,181,71,.35); */

  /* never the accent: keyboard focus, a chosen option, errors, warnings, success */
  --focus:#F5F5F7;
  --ring:#F5F5F7;
  --err:#FF6B6B;      --err-soft:rgba(255,107,107,.14);
  --warn:#FBBF24;     --warn-soft:rgba(251,191,36,.14);
  --ok:#4ADE80;       --ok-soft:rgba(74,222,128,.14);

  /* neutrals */
  --black:#141416;    --paper:#141416;                 /* the page */
  --bg-elev:#19191C;                                   /* the flow's panel, sheets */
  --surface:#1F1F23;                                   /* tiles and cards */
  --gray-1:#27272C;   --surface-2:#27272C;             /* fields, a chosen card's fill */
  --gray-2:rgba(255,255,255,.08);
  --line:rgba(255,255,255,.08);   --hair:rgba(255,255,255,.08);
  --line-2:rgba(255,255,255,.18); --hair-2:rgba(255,255,255,.18);
  --line-control:rgba(255,255,255,.36);                /* the edge of a field, an outline button, an option card */
  --ink:#F5F5F7;      --ink-2:#F5F5F7;   --white:#FFFFFF;
  --gray-7:#A1A1A6;                                    /* secondary text */
  --gray-5:#8E8E93;   --text-3:#8E8E93;                /* tertiary text, placeholders: 4.56:1 on the field fill, never darker */
  --gray-3:#D9D9DE;   --silver:#D9D9DE;
  --silver-dim:rgba(217,217,222,.42);
  --halo:rgba(217,217,222,.22);                        /* the soft light behind a card */
  --glass:rgba(25,25,28,.72);  --glass-2:rgba(39,39,44,.6);
  --laser:0 0 10px rgba(255,255,255,.28);

  /* type: the system stack everywhere, the storefront's own (site-v2.css); no monospace labels. The web fonts
     this page loads are for the text a customer puts on the card, never for the page itself. */
  --font-head:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",system-ui,sans-serif;
  --font-display:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",system-ui,sans-serif;
  --font-body:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",system-ui,sans-serif;
  --font-mono:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",system-ui,sans-serif;

  /* shape and space */
  --r-sm:12px; --r:18px; --r-lg:28px;
  --control-h:52px;
  --shell:1200px; --pad:clamp(16px,4vw,32px);
  --header-h:64px;
  --ease:cubic-bezier(.2,.7,.2,1);
  --shadow:0 10px 30px -14px rgba(0,0,0,.7), 0 1px 0 rgba(255,255,255,.04) inset;
}

/* ============================================================
   2. PAGE
   ============================================================ */
html{ background:var(--black); }
body.create-page{
  background-color:var(--black); background-image:none;
  color:var(--ink); font-size:1rem; line-height:1.6;
}
/* what the script hides stays hidden, whatever display its class sets */
[hidden]{ display:none !important; }
h1,h2,h3{ letter-spacing:-.022em; font-weight:600; }

.sr-only{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
::selection{ background:var(--silver); color:#141416; }

/* the way past the header for a keyboard: off screen until it has focus */
.skip-link{
  position:fixed; left:12px; top:-80px; z-index:300; display:inline-flex; align-items:center; min-height:44px; padding:0 18px;
  border-radius:999px; background:var(--ink); color:#000; font:500 1rem/1 var(--font-body); text-decoration:none;
}
.skip-link:focus{ top:10px; }

/* the line under the page */
.create-foot{ margin-top:28px; font-size:.8125rem; line-height:1.6; color:var(--gray-5); }
.create-foot a{ color:var(--gray-3); text-underline-offset:3px; }

/* ============================================================
   3. FOCUS — one ring everywhere: 2px, white, only for the keyboard.
   ============================================================ */
:focus-visible{ outline:2px solid var(--focus); outline-offset:3px; }
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible, summary:focus-visible, label.check:focus-visible{
  outline:2px solid var(--focus); outline-offset:2px;
}
.btn:focus-visible{ outline:2px solid var(--focus); outline-offset:3px; }
/* a heading the script moved the keyboard to (a new step) is a place to read from, not a control */
h2[tabindex="-1"]:focus{ outline:none; }
/* the design area takes focus for the editor's shortcuts. On a wide screen the ring goes on the card's panel
   alone, just inside its edge: round the whole area it would be painted over by the tools panel beside the
   card and cut off by the flow's panel (overflow:clip in create-page.css). */
#editor.ed.gd:focus-visible{ outline:2px solid var(--focus); outline-offset:4px; border-radius:20px; }
@media (min-width:900.02px){
  #editor.ed.gd:focus-visible{ outline:none; }
  #editor.ed.gd:focus-visible > .gd-stagewrap{ outline:2px solid var(--focus); outline-offset:-2px; }
}
/* controls whose real input is invisible show the ring on what the customer sees */
.gd-upload-btn:focus-within, .file-drop:focus-within{ outline:2px solid var(--focus); outline-offset:3px; }
.gd-upload-btn:focus-within:not(:has(input:focus-visible)), .file-drop:focus-within:not(:has(input:focus-visible)){ outline:none; }
.gd-search:focus-within{ border-color:rgba(255,255,255,.55); }

/* ============================================================
   4. THE FLOW HEADER — glass, hairline, the storefront's logo.
   Its layout is in section 25.
   ============================================================ */
.eng-header.create-bar{
  background:rgba(20,20,22,.78);
  backdrop-filter:saturate(180%) blur(20px); -webkit-backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid var(--hair);
}
.gd-bar-logo{ display:inline-flex; align-items:center; flex:none; min-height:44px; line-height:0; }
.eng-header .gd-bar-logo img{ display:block; width:auto; height:30px; max-width:none; opacity:1; }
@media (min-width:960px){ .eng-header .gd-bar-logo img{ height:36px; } }      /* as in chrome.css */
.gd-bar .back-link{
  display:inline-flex; align-items:center; gap:6px; min-height:44px; min-width:44px; padding:0 12px 0 8px; margin-left:-8px;
  border-radius:999px; font-size:.9375rem; font-weight:500; color:var(--gray-7);
}
@media (hover:hover){ .create-bar .back-link:hover{ background:rgba(255,255,255,.07); color:var(--ink); } }
/* the page's one h1: what is being made */
.gd-bar-title{
  margin:0; font:600 .9375rem/1.2 var(--font-body); letter-spacing:-.01em; text-transform:none; color:var(--ink); text-align:left; white-space:nowrap;
}

/* ============================================================
   5. STEP DOTS — the four steps as dots joined by a hairline
   (ol.flow-steps#progress, in the header). create.js marks the
   current step (li.is-now, aria-current="step") and the finished
   ones (li.is-done, whose button goes back to that step).
   A step to come is an 8px dot; a finished one a ticked silver dot;
   the current one stretches into a short pill in the accent.
   Wide screens: dot and label side by side, in the header row.
   Phones: a row of its own under the header, label under dot; on
   the Design step only the dots sit in the one top bar (section 43).
   ============================================================ */
.flow-steps{ display:flex; align-items:center; gap:0; margin:0; padding:0; list-style:none; }
.flow-step{ display:flex; align-items:center; flex:0 1 auto; min-width:0; }
/* the hairline that joins a step to the one before it */
.flow-step + .flow-step::before{ content:""; flex:1 1 24px; min-width:12px; width:40px; height:1px; margin:0 4px; background:var(--line-2); }
.flow-step.is-done + .flow-step::before{ background:var(--silver-dim); }
.step-btn{
  display:inline-flex; align-items:center; gap:8px; min-height:44px; min-width:28px; padding:0 6px; border:0; border-radius:999px; background:none;
  color:var(--gray-5); font:500 .875rem/1.2 var(--font-body); white-space:nowrap; cursor:default;
}
.step-btn:not(:disabled){ cursor:pointer; }
.step-dot{
  position:relative; flex:none; width:8px; height:8px; border-radius:99px; background:var(--line-control);
  transition:width .25s var(--ease), height .25s var(--ease), background-color .25s var(--ease);
}
.step-lbl{ min-width:0; overflow:hidden; text-overflow:ellipsis; }
.step-n{ font-variant-numeric:tabular-nums; }
/* done: a larger silver dot with a tick */
.flow-step.is-done .step-dot{ width:16px; height:16px; background:var(--silver); }
.flow-step.is-done .step-dot::after{
  content:""; position:absolute; inset:0;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23141416' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 12.5l4.2 4.2L18.5 8'/%3E%3C/svg%3E") center/11px no-repeat;
}
.flow-step.is-done .step-btn{ color:var(--gray-7); }
/* now: the dot stretches into a pill */
.flow-step.is-now .step-dot{ width:24px; background:var(--accent); }
.flow-step.is-now .step-btn{ color:var(--ink); font-weight:600; }
@media (hover:hover){ .step-btn:not(:disabled):hover{ color:var(--ink); background:rgba(255,255,255,.06); } }
.step-btn:not(:disabled):active .step-dot{ transform:scale(.9); }
.step-btn:focus-visible{ outline:2px solid var(--focus); outline-offset:-2px; }
@media (prefers-reduced-motion:reduce){ .step-dot{ transition:none; } .step-btn:not(:disabled):active .step-dot{ transform:none; } }

/* ============================================================
   6. BUTTONS — the storefront's pill. Primary: white, black text.
   Secondary (.btn-ghost): an outline. 52px tall, 44px small.
   Hover only where there is a pointer; press scales in; a busy
   button (.loading) shows a spinner and takes no second press.
   ============================================================ */
.btn{
  --bg:#F5F5F7; --fg:#000000; --bd:#F5F5F7;
  min-height:var(--control-h); padding:0 26px; gap:10px; border-width:1.5px;
  font:500 1rem/1.2 var(--font-body); letter-spacing:-.005em;
  transition:transform .18s var(--ease), background-color .18s, border-color .18s, color .18s, opacity .18s;
}
.btn-white{ --bg:#F5F5F7; --fg:#000000; --bd:#F5F5F7; }
.btn-ghost{ --bg:transparent; --fg:var(--ink); --bd:var(--line-control); }
.btn-sm{ min-height:44px; padding:0 18px; font-size:.9375rem; }
.btn-lg{ min-height:56px; padding:0 30px; font-size:1.0625rem; }
/* (the selectors repeat engraving.css's own hover rules, which turn a hovered button into an outline) */
.btn:hover{ transform:none; box-shadow:none; }
.btn-white:hover,
.btn:not(.btn-white):not(.btn-ghost):not(.btn-outline-white):hover{ --bg:#F5F5F7; --fg:#000000; --bd:#F5F5F7; }
.btn-ghost:hover{ --bg:transparent; --bd:var(--line-control); }
@media (hover:hover){
  .btn-white:not(:disabled):hover,
  .btn:not(.btn-white):not(.btn-ghost):not(.btn-outline-white):not(:disabled):hover{ --bg:#FFFFFF; --bd:#FFFFFF; }
  .btn-ghost:not(:disabled):hover{ --bg:rgba(255,255,255,.06); --bd:rgba(255,255,255,.6); }
}
.btn:not(:disabled):active{ transform:scale(.965); }
.btn-white:not(:disabled):active,
.btn:not(.btn-white):not(.btn-ghost):not(.btn-outline-white):not(:disabled):active{ --bg:#D9D9DE; --bd:#D9D9DE; }
.btn:disabled, .btn[aria-disabled="true"]{ opacity:.4; cursor:not-allowed; }
.btn.loading{ opacity:1; pointer-events:none; cursor:progress; }
.btn.loading[aria-busy="true"]{ opacity:.8; }
.flow-foot #btn-next{ box-shadow:none; }
/* the editor's small controls press in too */
.gd-choice, .gd-tile, .ed-add, .gd-add, .lt span{ transition:transform .18s var(--ease), background-color .18s, border-color .18s, color .18s; }
/* "Free Design Help": a quiet outline pill beside the legend */
.gd-help-link{
  min-height:36px; padding:0 14px; border:1.5px solid var(--line-control); background:transparent; color:var(--ink);
  font:500 .8125rem/1 var(--font-body); letter-spacing:0; box-shadow:none;
}
.gd-help-link:hover{ box-shadow:none; transform:none; }
@media (hover:hover){ .gd-help-link:hover{ background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.6); } }
/* "Add another design" */
.gd-add{ min-height:44px; max-width:100%; text-align:left; background:transparent; border:1.5px solid var(--line-control); font:500 .9375rem/1.25 var(--font-body); }
.gd-add small{ flex:none; white-space:nowrap; font-size:.75rem; letter-spacing:0; color:var(--gray-7); }
.gd-add:hover{ border-color:var(--line-control); background:transparent; }
@media (hover:hover){ .gd-add:hover{ border-color:rgba(255,255,255,.6); background:rgba(255,255,255,.06); } }
.gd-add-note{ font-size:.8125rem; }
/* the white upload button */
.gd-upload-btn{ background:#F5F5F7; color:#000; font:500 1rem/1.2 var(--font-body); }
.gd-upload-btn.loading{ pointer-events:none; opacity:.6; }
/* text buttons */
.link-btn{
  padding:0; border:0; background:none; color:var(--ink); font:inherit; font-weight:500; cursor:pointer;
  text-decoration:underline; text-decoration-color:var(--line-control); text-underline-offset:3px;
}
@media (hover:hover){ .link-btn:hover{ text-decoration-color:currentColor; } }

/* ============================================================
   7. FIELDS, TICK BOXES, SMALL LABELS
   A field is 52px tall, 12px corners, the field fill, a 1.5px edge;
   16px text (no zoom on iOS). An error turns the edge red and shows
   its message with an icon; a valid link shows a green tick.
   ============================================================ */
input[type=text],input[type=email],input[type=tel],input[type=number],input[type=url],input[type=search],select,textarea{
  min-height:var(--control-h); padding:13px 14px; border-radius:var(--r-sm);
  background-color:var(--gray-1); border:1.5px solid var(--line-control); color:var(--ink);
  font-family:var(--font-body); font-size:1rem; line-height:1.4;
  transition:border-color .15s, box-shadow .15s, background-color .15s;
}
textarea{ min-height:112px; }
@media (hover:hover){ input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):hover, select:hover, textarea:hover{ border-color:rgba(255,255,255,.55); } }
input:focus, select:focus, textarea:focus{ border-color:rgba(255,255,255,.55); box-shadow:none; }
input:disabled, select:disabled, textarea:disabled{ opacity:.5; cursor:not-allowed; }
::placeholder{ color:var(--text-3); opacity:1; }
input[aria-invalid="true"], textarea[aria-invalid="true"], select[aria-invalid="true"],
.field.has-err input, .field.has-err select, .field.has-err textarea{ border-color:var(--err); }
/* the select's arrow. create-page.css sets `select{background:...}`, a shorthand that resets
   repeat and position, so every longhand is restated here. */
select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23F5F5F7' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 14px center; background-size:14px 14px;
  padding-right:40px; -webkit-appearance:none; appearance:none;
}
select::-ms-expand{ display:none; }

/* a field: its label, the control, then a hint or what is wrong */
.field{ margin-bottom:16px; }
.field > span{ margin-bottom:8px; font-size:.875rem; font-weight:500; line-height:1.35; color:var(--ink); }
.flow-create .field.req > span::after, .fb-card .field.req > span::after{ color:var(--gray-7); }
.field .muted{ font-weight:400; color:var(--gray-7); }
.field > .hint{ margin:8px 0 0; font-size:.8125rem; font-weight:400; line-height:1.45; color:var(--gray-7); }
.field.req > .hint::after, .field.req > .err::after, .field.req > .zip-hint::after{ content:none; }
/* what is wrong: an icon and words, never the color alone */
.field > .err, .check-err{
  margin:8px 0 0; padding-left:22px; font-size:.8125rem; font-weight:500; line-height:1.45; color:var(--err);
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF6B6B' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5M12 16.4v.1'/%3E%3C/svg%3E") left 1px/16px no-repeat;
}
.check-err{ margin:8px 0 12px; }
/* the ZIP look-up's answer under its field (create-v2.js), e.g. "Palm Bay, FL" */
.field > .zip-hint{ display:block; margin:8px 0 0; min-height:0; font-size:.8125rem; font-weight:500; color:var(--ok); }
.field > .zip-hint.is-warn{ color:var(--warn); }
.field > .zip-hint:empty{ display:none; }

/* a tick box with its sentence: the whole row is the target */
.check{
  align-items:flex-start; gap:14px; min-height:52px; padding:14px 16px; margin-bottom:10px; border-radius:var(--r-sm);
  background:var(--surface); border:1px solid var(--line-2);
  transition:border-color .15s var(--ease), background-color .15s var(--ease);
}
.check input{ width:22px; height:22px; margin:1px 0 0; accent-color:var(--ink); }
.check span{ font-size:.9375rem; line-height:1.5; }
@media (hover:hover){ .check:hover{ border-color:var(--line-control); background:var(--surface); } }
.check:has(input:checked){ border-color:var(--silver-dim); background:var(--gray-1); }
.check.has-err{ border-color:var(--err); background:var(--err-soft); }
/* the keyboard's ring goes round the whole row (where :has() is not known, the box keeps its own ring) */
@supports selector(:has(*)){
  .check:has(input:focus-visible){ outline:2px solid var(--focus); outline-offset:2px; }
  .check input:focus-visible{ outline:none; }
}

/* small labels: plain words at 13px, never monospace capitals */
.mono-label, .form-h, #step-count, .gd-tray-h, .gd-dblank, .rv-strip figcaption, .rv .rv-h h3,
.flow-foot .tot small, .gd-tool-h, .gd-legend, .file-drop .file-name, .gd-tool output{
  font-family:var(--font-body); letter-spacing:0; text-transform:none;
}
.mono-label{ display:block; margin:0 0 8px; font-size:.8125rem; font-weight:500; line-height:1.35; color:var(--gray-7); }
/* the name of a group of controls inside a step */
.form-h{
  display:block; width:100%; margin:28px 0 14px; padding:24px 0 0; border-top:1px solid var(--hair);
  font-size:1.0625rem; font-weight:600; line-height:1.3; letter-spacing:-.01em; color:var(--ink);
}
.form-h--first{ margin-top:0; padding-top:0; border-top:0; }
.gd-tool-h{ font-size:.8125rem; font-weight:500; color:var(--gray-7); }
.gd-tool output{ font-size:.8125rem; font-weight:600; font-variant-numeric:tabular-nums; }
.gd-tray-h{ font-size:.8125rem; font-weight:500; color:var(--gray-7); }
.gd-dblank{ font-size:.75rem; color:var(--gray-5); }
.file-drop .file-name{ font-size:.8125rem; color:var(--gray-3); }
.pv-k{ margin:0 0 8px; font:600 .8125rem/1.3 var(--font-body); letter-spacing:.06em; text-transform:uppercase; color:var(--accent-text); }

/* the reference file box */
.file-drop{ border-radius:var(--r-sm); border:1.5px dashed var(--line-control); background:var(--surface); }
.file-drop:hover, .file-drop.drag{ border-color:rgba(255,255,255,.6); background:var(--gray-1); }
.file-drop small{ color:var(--gray-7); font-size:.8125rem; }
.file-drop.has-file{ border-style:solid; border-color:var(--ok); background:var(--ok-soft); }
.file-preview{ width:auto; height:auto; max-width:100%; }
/* the address read back */
.addr-preview{ border-radius:var(--r-sm); background:var(--surface); border:1px solid var(--hair); border-left:2px solid var(--silver-dim); font-family:var(--font-body); font-size:.9375rem; }
.addr-preview.empty{ font-style:normal; color:var(--gray-5); }
.ship-to{ margin:4px 0 8px; }
.disclaimer-box{ border-radius:var(--r-sm); border-color:var(--hair); background:transparent; color:var(--gray-7); font-size:.8125rem; line-height:1.55; }

/* ============================================================
   8. THE CARD ON THE STAGE
   .ed-stage keeps padding 0, as editor.js measures it. The stage
   holds the card's shape before the editor starts, so nothing
   moves when it does: the bare <canvas> fills the stage at
   1013:638, exactly the box the editor then gives it.
   ============================================================ */
.gd .ed-stage{ aspect-ratio:1013 / 638; }
.gd .ed-stage > canvas{ display:block; width:100%; height:100%; border-radius:4%/6.5%; background:#0a0a0b; }
.ed-stage .canvas-container{
  box-shadow:0 0 0 1px rgba(255,255,255,.12), 0 18px 34px rgba(0,0,0,.5), 0 40px 80px rgba(0,0,0,.45);
}
.ed.gd.is-drawing .ed-stage .canvas-container{
  box-shadow:0 0 0 2px rgba(245,245,247,.6), 0 18px 34px rgba(0,0,0,.5), 0 40px 80px rgba(0,0,0,.45);
}
.gd .ed-empty span{ font-size:.875rem; color:var(--gray-3); }
/* the heading of the Design step: small, the card is what the step shows */
.fstep .design-h{ margin:0; font-size:1.25rem; line-height:1.2; letter-spacing:-.015em; }
/* what the two colors on the card mean */
.gd-legend{ gap:6px 16px; font-size:.8125rem; color:var(--gray-7); }
.gd-legend-key{ display:inline-flex; align-items:center; gap:8px; }
.gd-legend .sw{ margin-right:0; border-radius:4px; }
.gd-legend .sw.silver{ background:var(--silver); box-shadow:none; }
.gd-legend .sw.black{ background:#0A0A0B; border:1px solid var(--line-control); }

/* ============================================================
   9. DOCK, TABS, TILES, TRAY, TIP
   A chosen tab, tile or tool is white or silver, never the accent.
   ============================================================ */
.dk{ font:500 .75rem/1 var(--font-body); }
.dk.primary svg{ box-shadow:none; }
.dk.danger:hover:not(:disabled){ color:#FFC2C2; }
.dk.danger:hover:not(:disabled) svg{ background:rgba(255,107,107,.18); }
.gd-tool{ border-radius:var(--r-sm); background:var(--surface); border:1px solid var(--line-2); }
.gd-tool .tb.text{ min-height:36px; font-size:.8125rem; }
.gd-font{ min-height:44px; border-radius:var(--r-sm); }
.ed-tabs button.on{ background:rgba(255,255,255,.08); color:var(--ink); box-shadow:inset 0 -2px 0 var(--ink); }
.ed-tabs button{ font:500 .75rem/1.1 var(--font-body); }
.gd-tablist{ display:flex; flex:none; flex-direction:inherit; gap:inherit; }      /* the tabs proper; the Canva link stands after them */
.gd-tab-canva{ font:600 .75rem/1.1 var(--font-body); }
/* (a tile, a chip or a button you choose has the edge of a control: --line-control, 3:1 on the panel) */
.gd-chip{ min-height:36px; border-color:var(--line-control); font-size:.8125rem; }
.gd-tile, .ed-tile{ border-radius:var(--r-sm); background:var(--surface); border-color:var(--line-control); font-size:.75rem; }
.gd-icon{ border-radius:var(--r-sm); background:var(--surface); border-color:var(--line-control); font-size:.75rem; }
@media (hover:hover){
  .gd-tile:hover, .gd-icon:hover{ border-color:rgba(255,255,255,.6); box-shadow:none; transform:none; }
}
.ed-add{ min-height:var(--control-h); border-radius:var(--r-sm); background:var(--surface); border-color:var(--line-control); }
.ed-note{ font-size:.8125rem; color:var(--gray-7); }
.gd-brush{ min-height:44px; border-radius:var(--r-sm); border-color:var(--line-control); font-size:.75rem; }
.gd-more{ min-height:44px; }
.gd-search{ min-height:44px; background:var(--gray-1); border:1.5px solid var(--line-control); }
.gd-search input{ min-height:0; border:0; background:transparent; }
/* the starting points */
.gd-start-h{ font-family:var(--font-head); font-weight:600; font-size:1.0625rem; letter-spacing:-.01em; }
.gd-choice{ min-height:72px; border-radius:var(--r); background:var(--surface); border:1px solid var(--line-control); }
.gd-choice:first-of-type{ border-color:var(--line-control); }
.gd-choice:hover{ transform:none; background:var(--surface); border-color:var(--line-control); }
@media (hover:hover){ .gd-choice:hover{ border-color:rgba(255,255,255,.6); background:var(--gray-1); } }
.gd-choice b{ font-family:var(--font-head); font-weight:600; font-size:1rem; }
.gd-choice small{ font-size:.8125rem; color:var(--gray-7); }
a.gd-choice{ text-decoration:none; }
.gd-canva-cta{ border-radius:var(--r); background:var(--surface); }
.gd-canva-cta small{ font-size:.8125rem; color:var(--gray-7); }
/* the designs tray: the design on the canvas has the white ring */
.gd-tray{ border-radius:var(--r); background:var(--surface); border:1px solid var(--hair); }
.gd-dtile.on .gd-dpick{ border-color:var(--ring); box-shadow:0 8px 20px rgba(0,0,0,.5); }
.gd-dpick img{ height:100%; }
.gd-dbar > span{ font-size:.8125rem; }
/* the pointer to "Add" on a blank card */
.gd-tip{ background:var(--ink); color:#141416; border-radius:var(--r-sm); box-shadow:0 12px 30px rgba(0,0,0,.5); font-size:.875rem; }
.gd-tip::after{ border-top-color:var(--ink); }
/* the more menu */
.gd-menu{ border-radius:var(--r); background:var(--gray-1); border:1px solid var(--line-2); backdrop-filter:none; -webkit-backdrop-filter:none; }
.gd-menu button{ min-height:44px; font-size:.9375rem; color:var(--ink); }
.gd-menu button.danger:hover{ color:#FFC2C2; background:rgba(255,107,107,.14); }
.gd-menu-note{ font-size:.8125rem; color:var(--gray-7); }
.tb.danger:hover:not(:disabled){ border-color:rgba(255,107,107,.55); color:#FFC2C2; background:rgba(255,107,107,.12); }

/* ============================================================
   10. REVIEW HERO, PREVIEW STAGE — a plain dark stage with one
   soft light, no photograph behind the card.
   ============================================================ */
.rv-hero, .gd-preview-stage{
  background:radial-gradient(90% 70% at 50% 0%, var(--halo), transparent 62%), #0E0E10;
}
.rv-hero::before, .gd-preview-stage::before{ content:none; }
.review{ border-radius:var(--r); background:var(--surface); border-color:var(--hair); }
.rv.rv-total{ background:transparent; }
.rv-hero img, .gd-preview-stage img{ height:auto; }
.rv-strip figcaption{ font-size:.8125rem; color:var(--gray-7); }

/* ============================================================
   11. MESSAGES
   ============================================================ */
.notice{ border-radius:var(--r-sm); font-size:.9375rem; line-height:1.5; }
.notice.err{ background:var(--err-soft); border-color:rgba(255,107,107,.45); color:#FFC2C2; }
.notice.warn{ background:var(--warn-soft); border-color:var(--warn); color:var(--ink); }
.notice.ok{ background:var(--ok-soft); border-color:rgba(74,222,128,.45); color:#B7F0CB; }
.notice .link-btn{ color:inherit; }

/* ============================================================
   12. REDUCED MOTION — nothing moves on hover or press, steps
   and sheets change at once.
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .btn, .btn:not(:disabled):active, .lt:active span, .gd-choice:active, .gd-tile:active, .ed-add:active, .gd-add:active,
  .gd-dpick:hover, .gd-tab-canva:hover, .gd-upload-tile:hover, .gd-upload-btn:active{ transform:none; transition:none; }
  .fstep.active{ animation:none; }      /* the fade engraving.css gives a step; this file's own entrance is in section 42 */
  html{ scroll-behavior:auto; }
}

/* ================================================================
   LAYOUT
   Grid and flex placement of pieces that are already in the markup.
   Breakpoint: `min-width:900.02px` throughout, the complement of
   create.js's own `matchMedia('(max-width:900px)')` in placeChrome()
   (901px left zoomed windows 900.5px wide matching neither).
   Step-scoped rules hang on state create.js writes: `body.gd-designing`
   (the editor is on screen), `body.gd-edit` (an order's design is
   being edited) and `#flow[data-step]` (the step number).
   ================================================================ */

/* ----------------------------------------------------------------
   25. THE FLOW HEADER — sticky: back, the logo, the page's name,
   and the step dots at the right. (Phones: section 43.)
   ---------------------------------------------------------------- */
.eng-header.create-bar{ position:sticky; top:0; z-index:50; }
@media (min-width:900.02px){
  .gd-bar{ display:flex; align-items:center; gap:20px; }
  .gd-bar-nav, .gd-bar-logo{ flex:none; }
  .gd-bar-title{ flex:none; padding-left:20px; border-left:1px solid var(--hair-2); }
  #progress{ flex:0 1 auto; min-width:0; margin-left:auto; }
}
@media (min-width:900.02px) and (max-width:1139px){
  /* no room for the name beside the labelled dots: it stays for screen readers */
  .gd-bar-title{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0; overflow:hidden; clip:rect(0 0 0 0); }
}

/* ----------------------------------------------------------------
   27. DESIGN STEP SHELL — edge to edge, a dark workbench with a
   faint dot grid. While the editor is on screen (body.gd-designing)
   the flow has no panel and the step takes the whole width; the other
   steps keep the panel (section 42).
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  body.gd-designing .flow-create{
    background:none; border:0; box-shadow:none; border-radius:0;
  }
  /* less air above the canvas on this step, so the whole tool cluster
     fits above the sticky footer (see .ed-stage in section 32) */
  body.gd-designing .create-main{ padding-top:8px; }
  body.gd-designing .flow-head{ padding:0; }
  body.gd-designing .flow-body{ padding:6px 0 20px; }
  body.gd-edit .flow-head{ padding-top:14px; }
  /* The page's wrapper is as wide as the editor needs, on every step: each step's panel sets its own
     width (section 42), so nothing moves sideways when the editor opens. (`.wrap`'s width comes from
     `width:min(100% - var(--pad)*2, var(--shell))`, and `.wrap.wide` caps it with max-width: both are set.) */
  .wrap.wide{
    width:min(100% - var(--pad)*2, 1320px);
    max-width:1320px;
  }
}

/* the card's workbench: a stage darker than the page, with a very faint dot grid.
   .ed-stage itself keeps padding 0 (editor.js's fit() measures it); this is its parent. */
@media (min-width:900.02px){
  .gd-stagewrap{
    background-color:#0E0E10;
    background-image:radial-gradient(circle, rgba(255,255,255,.07) 1px, transparent 1.5px);
    background-size:22px 22px;
    border:1px solid var(--hair);
    border-radius:var(--r-lg);
    padding:clamp(16px,2vw,24px);
  }
}

/* ----------------------------------------------------------------
   28. TWO-COLUMN DESKTOP GRID + DOCKED TOOLS PANEL
   Same grid (#editor.ed.gd) create-page.css already builds — widens
   the fixed column from 340px to the brief's 400-420px and makes the
   panel a flush, full-height, own-scrolling dock instead of a
   floating glass card sized to its own content.
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  #editor.ed.gd{
    grid-template-columns:minmax(0,1fr) 412px;
    column-gap:0;
  }
  /* #editor's direct children are .gd-stagewrap, .gd-designs,
     .gd-scrim (display:none) and .gd-side (.gd-legend/.gd-dockwrap
     live inside .gd-stagewrap in the markup itself — see section 32)
     — the simple 2-row column-1 stack create-page.css was already
     built for. Still made explicit, because the
     same sparse-auto-placement quirk as the app-bar fix above is
     real: .gd-designs alone carries an explicit `grid-column:1`
     (create-page.css), and items with a definite column but auto row
     are placed in an earlier algorithm pass than fully-auto items —
     so without an explicit row too, .gd-designs would jump the queue
     ahead of .gd-stagewrap (column:auto) and land in row 1, pushing
     the canvas to row 2. */
  .gd-stagewrap{ grid-column:1; grid-row:1; }
  .gd-designs{ grid-column:1; grid-row:2; }
  .gd-side{
    grid-row:1 / span 2; /* matches create-page.css's own original span for this 2-item stack */
    position:sticky;
    top:calc(var(--header-h) + 16px);
    /* sized for where the panel starts at first paint (~135px down:
       bar + step-1 chrome), so its bottom — the rail's last tabs —
       clears the sticky footer before any scrolling; the 468px floor
       keeps all seven rail tabs visible on very short windows */
    height:max(468px, calc(100vh - var(--header-h) - 164px));
    display:grid;
    grid-template-columns:76px minmax(0,1fr);
    align-content:start;
    background:var(--bg-elev);
    border:0; border-left:1px solid var(--hair);
    border-radius:0;
    padding:0;
    overflow:hidden; /* the rail and the panel scroll independently, not this box */
  }

  .gd-start{ grid-column:1 / -1; padding:22px; overflow-y:auto; }

  .ed-panel{
    grid-column:2; grid-row:1 / -1;
    height:100%; overflow-y:auto; overscroll-behavior:contain;
    padding:18px 18px 28px;
  }
}
/* Small desktops and iPad landscape: the 412px panel left the card
   only ~420px wide at 1024 (narrower than on the same iPad in
   portrait). Back to the live site's 340px there; the rail keeps its
   76px, which "Templates" needs. */
@media (min-width:900.02px) and (max-width:1199px){
  #editor.ed.gd{ grid-template-columns:minmax(0,1fr) 340px; }
}

/* ----------------------------------------------------------------
   29. VERTICAL ICON RAIL — tool tabs, never clipped, no arrows
   #gd-tabs already lays each button out icon-over-label internally
   (create-page.css's ".ed-tabs button{display:grid;justify-items:
   center;...}") — a rail item needs exactly that. Only the CONTAINER
   changes, from a horizontal scroller with prev/next arrows to a
   vertical column filling the rail's own height.
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  .gd-tabsrow{
    grid-column:1; grid-row:1 / -1;
    display:block; margin:0; padding:10px 4px;      /* 4px at the sides: "Templates" needs the rest of the rail */
    height:100%; overflow-y:auto; overflow-x:visible;
    border-right:1px solid var(--hair);
    scrollbar-width:none;
  }
  .gd-tabsrow::-webkit-scrollbar{ display:none; }
  /* matches `.gd-catsrow.scrollable .gd-catarrow`'s specificity so
     this wins on source order alone — no arrows at this width, ever */
  .gd-catsrow.scrollable .gd-catarrow{ display:none; }

  #gd-tabs.gd-tabs{
    display:flex; flex-direction:column; align-items:stretch;
    gap:3px; overflow:visible; width:100%; padding:0;
  }
  #gd-tabs.gd-tabs button, .gd-tabsrow .gd-tab-canva{
    width:100%; min-width:0; flex:0 0 auto;
    padding:11px 0 10px; border-radius:12px;      /* no side padding: the label has the button's whole width */
  }
  #gd-tabs.gd-tabs button.on{
    background:rgba(255,255,255,.08); color:var(--ink);
    box-shadow:inset 3px 0 0 0 var(--ink);
  }
}

/* ----------------------------------------------------------------
   30. CATEGORY CHIPS (icons tab + templates tab) — wrap, no arrows
   Same specificity trick as the rail's arrows above.
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  .gd-cats{ flex-wrap:wrap; overflow-x:visible; padding:2px 2px 4px; }
}

/* ----------------------------------------------------------------
   31. TEMPLATES GRID — two columns at this width (create-page.css),
   with more air between the tiles.
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  .gd-tpls{ gap:14px; }
}

/* ----------------------------------------------------------------
   32. UNDER-CANVAS TOOLBAR — one pill cluster, no separate box
   .gd-legend and .gd-dockwrap are children of .gd-stagewrap in the
   markup (site/create/index.html), after .gd-top and .ed-stage — not
   of #editor, which is why giving them a grid-row there did nothing.
   create.js's placeChrome() only moves #gd-dockwrap (with #gd-side
   and #gd-scrim) to <body> at ≤900px, and puts the dock back here on
   desktop.
   .gd-stagewrap DOM order is: .gd-top, .ed-stage, .gd-legend,
   .gd-dockwrap. Target visual order is: canvas, .gd-top pill,
   .gd-legend, .gd-dockwrap — i.e. everything already comes after
   .ed-stage except .gd-top, so a plain `column` flex + explicit
   `order` only on the two that need to move is enough; nothing here
   is a DOM move, only a visual-order change. The one side effect is
   the pill's "···" menu, which used to open downward into empty
   space: it now opens upward and is lifted above the dock (below).
   ---------------------------------------------------------------- */
@media (min-width:900.02px){
  .gd-stagewrap{
    display:flex; flex-direction:column; gap:10px;
  }
  /* Canvas first, and no taller than the viewport leaves room for: at
     first paint the pill, legend and dock must clear the sticky footer
     on laptop-height screens (900, 790, 730 px tall). 500px ≈ bar +
     the card's name and the heading above the card + pill/legend/dock
     + footer below it; 1.5878 is the card's 1013:638 aspect; 440px is the floor
     on very short windows. editor.js's fit() sizes the Fabric canvas
     from .ed-stage's clientWidth, so width is the safe lever (padding
     and aspect-ratio stay exactly as create-page.css sets them). */
  .ed-stage{
    order:1; align-self:center;
    width:min(100%, max(440px, calc((100vh - 500px) * 1.5878)));
  }
  /* Below ~1080px wide the column is too narrow for the nine-button
     dock, which wraps to two rows (+70px), so reserve that too. */
  @media (max-width:1079px){
    .ed-stage{ width:min(100%, max(400px, calc((100vh - 570px) * 1.5878))); }
  }
  .gd-top{ order:2; }
  .gd-legend{ order:3; }
  .gd-dockwrap{ order:4; }

  .gd-top{
    align-self:center; width:fit-content; max-width:100%;
    display:flex; align-items:center; gap:2px; margin:0; padding:6px;
    background:var(--surface); border:1px solid var(--line-2); border-radius:999px;
  }
  .gd-top-l{ padding-right:4px; margin-right:2px; border-right:1px solid var(--hair-2); }
  .gd-layer{ margin:0 2px; }
  .gd-top-r{ padding-left:4px; margin-left:2px; border-left:1px solid var(--hair-2); }

  /* The pill paints above the dock and the canvas's empty-state overlay
     (z 3), and its "···" menu opens UPWARD over the card: the pill sits
     under the canvas, so opening down would run across the dock and into
     the sticky footer. z 5 keeps the pill under the sticky footer (z 6)
     when the page scrolls. */
  .gd-top{ position:relative; z-index:5; }
  .gd-menu{ top:auto; bottom:calc(100% + 6px); }

  /* .gd-dockwrap holds two stacked rows: #gd-tool (the Rotate / Size /
     Font / Draw strip create.js opens) above .gd-dock. A column flexbox
     keeps that order and centers both; each shrinks to its content, so
     the "Add/Preview" state no longer renders as a wide mostly-empty
     bordered box. (As a row flexbox the strip squeezed in BESIDE the
     dock.) */
  .gd-dockwrap{ display:flex; flex-direction:column; align-items:center; margin-top:0; }
  /* an explicit width: shrink-to-fit under-measures the strip's range
     slider (flex-basis 140px) and wrapped "Reset" onto a second row */
  .gd-dockwrap > .gd-tool{ width:min(100%, 600px); }

  .gd-legend{ margin:0; width:fit-content; align-self:center; }
  /* while a Rotate / Size / Font / Draw strip is open, the legend steps
     aside, so the strip doesn't push the dock under the sticky footer.
     So it does while a text or an image is selected: their dock is two
     rows at every width (fifteen children with the separator, against
     the ten of a shape's, which fit one), and the legend's row is the
     room the second row needs to stay above the footer. */
  @supports selector(:has(*)){
    .gd-stagewrap:has(#gd-tool:not(.hidden)) .gd-legend,
    .gd-stagewrap:has(#gd-dock > :nth-child(11)) .gd-legend{ display:none; }
  }
}

/* ================================================================
   41. THE FLOW'S OWN COMPONENTS
   The picture badges, the option cards, the color swatches, the
   tinted mock-up, the price lines and the "we design it" brief. The
   numbers are the storefront's (site-v2.css is not loaded on this
   page): 18px cards, a white ring and a tick badge for a chosen
   option, 30px swatches in a 44px target, a 2px focus ring. A choice
   and keyboard focus are white (--ring, --focus), never the accent.
   ================================================================ */

.flow-create fieldset{ min-width:0; margin:0; padding:0; border:0; }
.flow-create legend:not(.sr-only){ display:block; width:100%; padding-inline:0; }

/* ---- .badge: says what a picture is ("Real card" = a photograph, "Design preview" = a render) ---- */
.badge{
  display:inline-flex; align-items:center; flex:none; min-height:24px; padding:0 10px; border-radius:999px;
  border:1px solid var(--line-control); font-size:.75rem; font-weight:600; line-height:1; letter-spacing:.02em;
  white-space:nowrap; color:var(--gray-7);
}
.badge-real{ background:var(--ink); border-color:var(--ink); color:#141416; }
.badge-preview{ background:rgba(20,20,22,.82); border-color:transparent; color:#F5F5F7; }

/* ---- .option-card: a large card you choose, around a radio.
   label.option-card > input + span.option-card-face (picture or icon, title, one line of help, a price).
   Chosen = a white ring, a faint fill and a tick badge on the corner; the focus ring is drawn on the card
   while its hidden input has keyboard focus. ---- */
.option-cards{ display:grid; gap:12px; }
.option-card{ position:relative; display:block; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.option-card > input{ position:absolute; top:0; left:0; width:1px; height:1px; margin:0; opacity:0; pointer-events:none; }
.option-card-face{
  position:relative; display:flex; align-items:center; gap:14px; min-height:76px; padding:14px 16px;
  border-radius:18px; background-color:var(--surface); border:1px solid var(--line-control);
  transition:transform .18s var(--ease), background-color .18s, border-color .18s, box-shadow .18s;
}
.option-card-face::after{
  content:""; position:absolute; top:-9px; right:-9px; width:24px; height:24px; border-radius:50%;
  background:var(--ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23141416' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 8'/%3E%3C/svg%3E") center/14px no-repeat;
  box-shadow:0 0 0 3px var(--bg-elev); transform:scale(0); transition:transform .18s var(--ease);
}
.option-card-media{ position:relative; flex:none; width:64px; aspect-ratio:4 / 3; border-radius:10px; overflow:hidden; background:#FFFFFF; }
.option-card-media--dark{ background:#0E0E10; }
.option-card-media img{ display:block; width:100%; height:100%; object-fit:cover; }
/* a render on a white ground is shown whole on its white tile; a photograph fills its tile */
.option-card-media:not(.option-card-media--dark) img{ object-fit:contain; }
.option-card-icon{ flex:none; display:grid; place-items:center; width:48px; height:48px; border-radius:12px; background:var(--gray-1); color:var(--ink); }
.option-card-icon svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.option-card-text{ flex:1 1 auto; display:grid; gap:2px; min-width:0; }
.option-card-title{ font-family:var(--font-head); font-size:1rem; font-weight:600; line-height:1.3; letter-spacing:-.012em; color:var(--ink); }
.option-card-help{ font-size:.875rem; line-height:1.45; color:var(--gray-7); }
.option-card-price{ flex:none; margin-left:auto; font-size:.875rem; font-weight:600; line-height:1.3; text-align:right; white-space:nowrap; font-variant-numeric:tabular-nums; color:var(--ink); }
.option-card-price small{ display:block; font-size:.75rem; font-weight:500; color:var(--gray-7); }
@media (hover:hover){
  .option-card:hover > input:not(:disabled):not(:checked) + .option-card-face{ border-color:rgba(255,255,255,.6); }
}
.option-card:active > input:not(:disabled) + .option-card-face{ transform:scale(.99); }
.option-card > input:checked + .option-card-face{ background-color:var(--gray-1); border-color:var(--ring); box-shadow:inset 0 0 0 1px var(--ring); }
.option-card > input:checked + .option-card-face::after{ transform:scale(1); }
.option-card > input:focus-visible + .option-card-face{ outline:2px solid var(--focus); outline-offset:3px; }
.option-card > input:disabled + .option-card-face{ opacity:.5; cursor:not-allowed; }
/* .option-card--stack: the picture on top, for the choice between the two cards (step 0; sized in section 42) */
.option-card--stack .option-card-face{ flex-direction:column; align-items:stretch; }
.option-card--stack .option-card-media{ width:100%; }
.option-card--stack .option-card-media .badge{ position:absolute; left:12px; bottom:12px; }
.option-card--stack .option-card-price{ margin-left:0; text-align:left; white-space:normal; }
.option-card--stack .option-card-price small{ display:inline; }
/* "Design in progress": this card has a draft from earlier in the visit */
.option-card-flag{
  align-self:flex-start; display:inline-flex; align-items:center; min-height:24px; padding:0 10px; border-radius:999px;
  border:1px solid var(--line-control); font-size:.75rem; font-weight:600; color:var(--ink);
}
@media (min-width:600px){
  .option-cards--2{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .option-card-media{ width:76px; }
  .option-cards--2 .option-card,.option-cards--2 .option-card-face{ height:100%; }
}
@media (max-width:420px){
  /* a narrow phone: the price drops under the text instead of squeezing it */
  .option-card:not(.option-card--stack) .option-card-face{ flex-wrap:wrap; }
  .option-card:not(.option-card--stack) .option-card-text{ flex:1 1 0; }
  .option-card:not(.option-card--stack) .option-card-price{ flex:1 1 100%; margin-left:58px; text-align:left; }
  .option-card:not(.option-card--stack) .option-card-price small{ display:inline; }
}
@media (forced-colors:active){
  .option-card > input:checked + .option-card-face{ border-color:Highlight; box-shadow:inset 0 0 0 2px Highlight; }
}
.src-opts{ margin-bottom:6px; }

/* ---- .swatches: the engraving colors as round dots with their name under each (never color alone).
   label.swatch > input + span.swatch-dot + span.swatch-label; create.js builds them from ENGRAVE_COLORS and
   gives each its color (--sw), its tick color (--sw-tick) and its finish (data-finish). ---- */
.swatches{ display:flex; flex-wrap:wrap; gap:2px; margin:0 0 0 -7px; padding:0; list-style:none; }
.swatch{
  position:relative; display:flex; flex-direction:column; align-items:center; gap:6px;
  min-width:44px; min-height:44px; padding:7px 2px 4px; border-radius:12px; cursor:pointer; -webkit-tap-highlight-color:transparent;
}
.swatch > input{ position:absolute; top:0; left:0; width:1px; height:1px; margin:0; opacity:0; pointer-events:none; }
.swatch-dot{
  position:relative; flex:none; display:block; width:30px; height:30px; border-radius:50%;
  background:var(--sw, #D9D9DE); box-shadow:inset 0 0 0 1px rgba(255,255,255,.3);
  transition:transform .18s var(--ease);
}
.swatch[data-finish="metallic"] .swatch-dot,.swatch-dot[data-finish="metallic"]{
  background:linear-gradient(135deg, rgba(255,255,255,.75) 0%, rgba(255,255,255,0) 44%, rgba(0,0,0,.32) 100%), var(--sw, #D9D9DE);
}
.swatch-label{ font-size:.75rem; font-weight:500; line-height:1.2; text-align:center; white-space:nowrap; color:var(--gray-7); }
/* the chosen color: a ring around the dot and a tick on it */
.swatch-dot::before{
  content:""; position:absolute; top:-5px; left:-5px; right:-5px; bottom:-5px; border-radius:50%;
  border:2px solid var(--ring); opacity:0; transform:scale(.86); transition:opacity .15s, transform .18s var(--ease);
}
.swatch-dot::after{
  content:""; position:absolute; top:0; left:0; right:0; bottom:0; opacity:0; background:var(--sw-tick, #141416);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 8'/%3E%3C/svg%3E") center/16px no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 8'/%3E%3C/svg%3E") center/16px no-repeat;
  transition:opacity .15s;
}
.swatch > input:checked + .swatch-dot::before{ opacity:1; transform:none; }
.swatch > input:checked + .swatch-dot::after{ opacity:1; }
.swatch > input:checked ~ .swatch-label{ color:var(--ink); }
@media (hover:hover){ .swatch:hover > input:not(:disabled):not(:checked) + .swatch-dot{ transform:scale(1.08); } }
.swatch:active > input:not(:disabled) + .swatch-dot{ transform:scale(.94); }
/* keyboard focus: a ring around the whole swatch, so it is never mistaken for the chosen ring */
.swatch:focus-within{ outline:2px solid var(--focus); outline-offset:1px; }
.swatch:focus-within:not(:has(input:focus-visible)){ outline:none; }
/* the narrowest phones: the seven share the row instead of the last one dropping under the others */
@media (max-width:380px){
  .swatches{ gap:0; margin-left:-4px; }
  .swatch{ flex:1 1 0; min-width:0; }
}
.swatch-field{ margin-top:0; }
.swatch-picked{ margin:10px 0 4px; font-size:.9375rem; color:var(--gray-7); }
.swatch-picked b{ color:var(--ink); font-weight:600; }
.swatch-field .hint{ margin:0; font-size:.8125rem; color:var(--gray-7); }
@media (forced-colors:active){
  .swatch-dot{ forced-color-adjust:none; }
  .swatch-dot::before{ border-color:Highlight; }
}

/* ---- the mock-up in the chosen engraving color: the silver render multiplied by the color.
   create.js wraps the customer's own mock-ups in .card-tint and writes the color to #flow as --engrave
   (and its id as data-engrave). Metallic silver, the color the editor draws in, needs no layer. ---- */
.card-tint{ position:relative; display:block; isolation:isolate; overflow:hidden; border-radius:4%/6.5%; }
.card-tint::after{ content:""; position:absolute; inset:0; z-index:2; background:var(--engrave, #FFFFFF); mix-blend-mode:multiply; pointer-events:none; }   /* above the picture, which Review lifts with its own z-index */
#flow[data-engrave="silver"] .card-tint::after{ content:none; }
.pkg-card3d .card-tint{ position:absolute; inset:0; }
/* Review: the frame and the tilt move from the picture to the tinted wrapper */
.rv-hero .card-tint{
  z-index:1; width:min(100%,520px); margin:0 auto;
  box-shadow:0 0 0 1px rgba(255,255,255,.12), 0 30px 60px rgba(0,0,0,.65); transform:rotate(-2deg);
}
.rv-hero .card-tint img{ width:100%; margin:0; border-radius:0; box-shadow:none; transform:none; }
.rv-hero .rv-strip .card-tint{ width:100%; transform:none; }
@media (max-width:640px){ .rv-hero .card-tint{ transform:none; } }
/* a card we design: the blank shows as the black card it is */
.rv-hero img.inv{ filter:invert(1) brightness(.86); }

/* ---- .price-lines: what the order costs, one row per line (label, a note under it, the amount), then the total.
   create.js fills every [data-price-lines] from priceLines() in eng-common.js. .price-box is the tile around it. ---- */
.price-lines{ display:grid; margin:0; }
.price-box{ padding:4px 18px; border-radius:var(--r); border:1px solid var(--hair); background:var(--surface); }
.price-line{ display:flex; align-items:baseline; justify-content:space-between; gap:16px; padding-block:14px; border-top:1px solid var(--hair); }
.price-line:first-child{ border-top:0; }
.price-line dt{ min-width:0; font-weight:500; color:var(--ink); }
.price-line-note{ display:block; margin-top:2px; font-size:.875rem; font-weight:400; line-height:1.45; color:var(--gray-7); }
.price-line dd{ flex:none; margin:0; font-weight:600; font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--ink); }
.price-line--total{ border-top-color:var(--hair-2); padding-block:16px; }
.price-line--total dt{ font-weight:600; }
.price-line--total dd{ font-family:var(--font-head); font-size:1.5rem; line-height:1; letter-spacing:-.02em; }
.rv-url{ word-break:break-all; }
.rv-color{ display:inline-flex; align-items:center; gap:8px; }
.rv-color .swatch-dot{ width:16px; height:16px; }

/* ---- Design, NFC business card: "We design it for you" (the brief takes the editor's place) ---- */
.brief{ max-width:640px; margin:0 auto; }
.brief-fee{ margin:0 0 20px; padding:14px 16px; border-radius:var(--r-sm); border:1px solid var(--hair); background:var(--surface); font-size:.9375rem; color:var(--gray-3); }
.brief-fee b{ color:var(--ink); }
.brief .file-drop{ margin-bottom:18px; }
.brief .dc{ margin:6px 0 0; }
.brief-switch{ margin:24px 0 0; }

/* ---- Details: the "Address confirmed" pill drops under the sentence when the row is too narrow for both,
   so the sentence keeps its width on phones ---- */
#addr-verify{ flex-wrap:wrap; }
#addr-verify > span{ flex:1 1 200px; min-width:0; }
#addr-verify:has(input:checked)::after{ font-family:var(--font-body); font-size:.75rem; font-weight:600; letter-spacing:0; text-transform:none; color:#141416; background:var(--silver); padding:5px 10px; }

/* ---- a draft the browser would not keep (#draft-warn): a warning above the step, not an error ---- */
.notice.draft-warn{ margin:0 0 16px; }

/* ---- an order's design that cannot be opened for editing: the message stands where the editor would.
   On phones the dock and the Add sheet live under <body> (placeChrome), so they are hidden by name. ---- */
.edit-stop{ max-width:640px; margin:0 auto; padding:24px 0 8px; }
.edit-stop .lead{ margin-bottom:8px; }
body.edit-stopped .gd-dockwrap, body.edit-stopped .gd-side, body.edit-stopped .gd-scrim{ display:none; }
/* an order being edited: the line under "Add another design" says how many designs its cards can carry */
body.gd-edit .gd-designs .gd-add-note:not(.hidden){ display:block; }

@media (prefers-reduced-motion:reduce){
  .option-card-face,.option-card-face::after,.swatch-dot,.swatch-dot::before,.swatch-dot::after{ transition:none; }
  .option-card:active > input:not(:disabled) + .option-card-face,.swatch:active > input:not(:disabled) + .swatch-dot{ transform:none; }
}


/* ================================================================
   42. STEPS ON A WIDE SCREEN
   The panel is as wide as the step needs: two large cards for the
   chooser, the choices beside the card and the price on Options, one
   reading column for Details and Review. The Design step has no
   panel: the editor takes the whole width (section 27).
   ================================================================ */
.flow-create{
  background:var(--bg-elev); border:1px solid var(--hair); border-radius:var(--r-lg);
  box-shadow:0 30px 80px -40px rgba(0,0,0,.8);
}
.flow-head{ padding:20px clamp(20px,3vw,40px) 0; }
.flow-body{ padding:clamp(20px,3vw,40px); }
/* the line that names the card is 44px tall from the first paint on (it is empty only on the chooser) */
.flow-topline{ justify-content:space-between; min-height:44px; }
#flow[data-step="0"] .flow-topline, html[data-boot="s0"] #flow:not([data-step]) .flow-topline{ min-height:0; }
/* the card this order is for, with "Change card" */
.flow-card{ display:flex; align-items:center; gap:12px; margin:0; font-size:.875rem; color:var(--gray-7); }
#card-name{ font-weight:600; color:var(--ink); }
.flow-card .link-btn{ display:inline-flex; align-items:center; min-height:44px; font-size:.875rem; }
/* "Step 1 of 4" is said by the dots; the label stays only while an order's design is edited, where it names the order */
.step-label{ display:none; }
body.gd-edit .step-label{ display:flex; flex-direction:row; align-items:baseline; justify-content:flex-start; gap:10px; text-align:left; font-size:.875rem; color:var(--gray-7); }
body.gd-edit #step-name{ display:inline; font:600 .9375rem/1.3 var(--font-body); letter-spacing:0; color:var(--ink); }
#step-count{ font-size:.875rem; color:var(--gray-7); white-space:normal; }

/* a step's own heading and the line under it */
.fstep h2{ margin:0 0 8px; font-size:clamp(1.8rem, 2.2vw + 1rem, 2.8rem); line-height:1.08; letter-spacing:-.028em; }      /* the storefront's h2 */
.fstep > .lead, .opt-main > .lead, .brief > .lead, .edit-stop > .lead{ margin:0 0 28px; max-width:56ch; font-size:1.0625rem; line-height:1.5; color:var(--gray-7); }
@media (prefers-reduced-motion:no-preference){ .fstep.active{ animation:step-in .3s var(--ease); } }
@keyframes step-in{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }

@media (min-width:900.02px){
  #flow[data-step="0"]{ max-width:1000px; }
  #flow[data-step="1"]:not(:has(#editor:not([hidden]))){ max-width:760px; }   /* the brief, or the message that an order's design cannot be opened */
  #flow[data-step="2"]{ max-width:1120px; }
  #flow[data-step="3"]{ max-width:760px; }
  #flow[data-step="4"]{ max-width:820px; }
  body.gd-designing #flow, body.gd-edit:not(.edit-stopped) #flow{ max-width:none; }
  /* while the scripts load (no data-step yet) the panel already has the shape of the step this visit is
     expected to open on (html[data-boot], set by the small script in the head), so nothing moves when it shows */
  html[data-boot="s0"] #flow:not([data-step]){ max-width:1000px; }
  html[data-boot="s2"] #flow:not([data-step]){ max-width:1120px; }
  html[data-boot="s3"] #flow:not([data-step]){ max-width:760px; }
  html[data-boot="s4"] #flow:not([data-step]){ max-width:820px; }
  html[data-boot="s1"] #flow:not([data-step]){ max-width:none; background:none; border:0; border-radius:0; box-shadow:none; }
  html[data-boot="s1"] #flow:not([data-step]) .flow-head{ padding:0; }
  html[data-boot="s1"] #flow:not([data-step]) .flow-body{ padding:6px 0 20px; }
  html[data-boot="s1"] .create-main:has(#flow:not([data-step])){ padding-top:8px; }
}
@media (max-width:900px){
  /* phones, Design step: the card's name is in the price sheet, not above the editor */
  html[data-boot="s1"] #flow:not([data-step]) .flow-head{ display:none; }
}

/* ---- the chooser: two large cards, a faint dot grid behind them ---- */
.chooser > .check-err{ position:relative; z-index:1; margin:0 0 14px; }      /* "Choose a card to continue", above the cards */
.fstep[data-step="0"]{ position:relative; }
.fstep[data-step="0"] > h2, .fstep[data-step="0"] > .lead{ text-align:center; margin-inline:auto; }
.chooser{ position:relative; margin-top:4px; }
.chooser::before{
  content:""; position:absolute; inset:-28px -12px; z-index:0; pointer-events:none;
  background-image:radial-gradient(circle, rgba(255,255,255,.07) 1px, transparent 1.5px); background-size:22px 22px;
  -webkit-mask-image:radial-gradient(ellipse at center, #000 30%, transparent 78%); mask-image:radial-gradient(ellipse at center, #000 30%, transparent 78%);
}
.chooser .option-cards{ position:relative; z-index:1; gap:16px; }
.option-card--stack .option-card-face{ gap:16px; padding:14px 14px 20px; border-radius:var(--r-lg); background-color:var(--surface); }
.option-card--stack .option-card-media{ border-radius:16px; aspect-ratio:16 / 9; }
/* the render's own ground is not quite the tile's white: its side edges fade into the tile */
.option-card--stack .option-card-media:not(.option-card-media--dark) img{
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent); mask-image:linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}
.option-card--stack .option-card-text{ gap:6px; padding-inline:6px; }
.option-card--stack .option-card-title{ font-size:1.375rem; letter-spacing:-.02em; }
.option-card--stack .option-card-help{ font-size:.9375rem; }
.option-card--stack .option-card-price{ padding-inline:6px; font-size:1.25rem; letter-spacing:-.01em; }
.option-card--stack .option-card-price small{ font-size:.875rem; letter-spacing:0; }
.option-card--stack .option-card-flag{ margin-left:6px; }
@media (min-width:900.02px){
  .chooser .option-cards{ gap:24px; }
  .option-card--stack .option-card-media{ aspect-ratio:3 / 2; }
  .option-card--stack .option-card-face{ padding:16px 16px 24px; }
}
@media (max-width:599px){
  /* a phone: shorter pictures, so both cards show on the first screen */
  .chooser .option-cards{ gap:12px; }
  .option-card--stack .option-card-face{ gap:12px; padding:12px 12px 16px; border-radius:22px; }
  .option-card--stack .option-card-media{ aspect-ratio:2 / 1; border-radius:14px; }
  .option-card--stack .option-card-text{ gap:4px; }
  .option-card--stack .option-card-title{ font-size:1.25rem; }
  .option-card--stack .option-card-price{ font-size:1.125rem; }
}

/* ---- Options: the choices on the left, the card and the price beside them ---- */
.opt-side{ margin-top:28px; }
#cards-box.cards-box{ display:block; padding:0; border:0; border-radius:0; background:none; }
.cards-meta{ gap:10px; }
.cards-qty p, .cards-locked p{ margin:10px 0 0; font-size:.875rem; color:var(--gray-7); }
.cards-locked b{ font-family:var(--font-head); font-size:1.25rem; font-weight:600; letter-spacing:-.015em; }
.cards-pricing{ padding-top:0; border-top:0; font-size:.875rem; color:var(--gray-7); }
.cards-pricing b{ font-weight:600; }
/* the customer's card as a product shot: a tile, a floor shadow, one soft light */
#cards-show.pkg-show{
  position:relative; isolation:isolate; height:240px; margin:0; border-radius:var(--r); border:1px solid var(--hair);
  background:radial-gradient(80% 70% at 50% 18%, var(--halo), transparent 70%), var(--surface);
}
#cards-show.pkg-show::before{
  content:""; position:absolute; left:50%; bottom:9%; width:58%; height:14%; z-index:0; transform:translateX(-50%);
  background:radial-gradient(ellipse, rgba(0,0,0,.6), rgba(0,0,0,0) 72%); filter:blur(4px);
}
.opt-side .form-h{ margin-top:24px; padding-top:0; border-top:0; }
.ship-note{ margin:12px 0 0; font-size:.875rem; color:var(--gray-7); }
@media (min-width:900.02px){
  .opt-cols{ display:grid; grid-template-columns:minmax(0,1fr) minmax(320px,380px); column-gap:clamp(32px,5vw,64px); align-items:start; }
  .opt-side{ position:sticky; top:calc(var(--header-h) + 24px); margin-top:0; }
}

/* the quantity stepper: minus, the number, plus */
.stepper{ gap:8px; margin-top:0; padding:4px; height:var(--control-h); background:var(--gray-1); border:1.5px solid var(--line-control); }
.stepper button{ width:44px; height:44px; border-radius:50%; font-size:1.25rem; }
.stepper button:disabled{ opacity:.35; cursor:not-allowed; }
.stepper button:not(:disabled):active{ transform:scale(.92); }
.stepper b{ min-width:40px; font-family:var(--font-head); font-size:1.25rem; font-weight:600; font-variant-numeric:tabular-nums; }
@media (prefers-reduced-motion:reduce){ .stepper button:not(:disabled):active{ transform:none; } }

/* ---- Options, NFC business card: what the card opens (its S3XY Profile page). A note, nothing to fill in ---- */
.np{ display:flex; gap:16px; margin:0 0 4px; padding:20px; border-radius:var(--r); background:var(--surface); border:1px solid var(--hair); }
.np-ico{ flex:none; display:grid; place-items:center; width:44px; height:44px; border-radius:50%; background:var(--gray-1); border:1px solid var(--hair); }
.np-ico svg{ width:22px; height:22px; fill:none; stroke:var(--accent); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.np-text{ min-width:0; }
.np-h{ margin:0; font-size:1.0625rem; font-weight:600; letter-spacing:-.01em; color:var(--ink); }
.np-p{ margin:6px 0 0; font-size:.9375rem; line-height:1.5; color:var(--gray-7); }
.np-url{ margin:10px 0 0; font-size:.9375rem; color:var(--gray-7); }
.np-url b{ font-weight:600; color:var(--ink); word-break:break-all; }
.np-url[hidden]{ display:none; }
.pf-page{ margin:2px 0 0; }
.pf-page b{ font-weight:600; color:var(--ink); word-break:break-all; }
.pf-page[hidden]{ display:none; }
.flow-create .field.is-valid > input{
  padding-right:48px; border-color:rgba(74,222,128,.7);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234ADE80' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 8'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 16px center; background-size:20px 20px;
}
.flow-create .field.has-err > input{ border-color:var(--err); background-image:none; }
.qty-max{ margin:10px 0 0; font-size:.875rem; color:var(--gray-7); }
.qty-max a{ color:var(--ink); text-underline-offset:3px; }
.dc{ margin-top:8px; }
.dc p{ margin:10px 0 0; font-size:.875rem; color:var(--gray-7); }
.design-links{ display:flex; flex-wrap:wrap; align-items:center; gap:0 20px; margin:2px 0 0; font-size:.9375rem; }
.design-links .link-btn{ display:inline-flex; align-items:center; min-height:44px; }

/* ---- Review & pay ---- */
.review{ overflow:hidden; }
.rv{ padding:20px clamp(16px,2.4vw,24px); }
.rv .rv-h{ margin-bottom:10px; min-height:28px; }
.rv .rv-h h3{ font-size:1.0625rem; font-weight:600; letter-spacing:-.01em; color:var(--ink); }
/* "Edit": the words stay small, the target is 44px */
.rv .edit{
  display:inline-flex; align-items:center; min-height:44px; margin:-8px -10px -8px 0; padding:0 10px; border:0;
  font:500 .9375rem var(--font-body); color:var(--ink); text-decoration:underline; text-decoration-color:var(--line-control); text-underline-offset:3px;
}
@media (hover:hover){ .rv .edit:hover{ text-decoration-color:currentColor; } }
.flow-create .rv dl{ grid-template-columns:8.8em minmax(0,1fr); font-size:.9375rem; }
.rv dt{ color:var(--gray-7); }
.flow-create .rv dl.price-lines{ grid-template-columns:minmax(0,1fr); gap:0; font-size:1rem; }
.rv .price-line dt{ color:var(--ink); }
.rv-top{ padding:0; }
.rv-hero{ border-radius:0; }
.rv-hero.idea p{ font-size:.9375rem; color:var(--gray-7); }
.rv-time{ margin:14px 0 0; font-size:.875rem; line-height:1.5; color:var(--gray-7); }
/* the agreements: one block, each row a 44px target; "Agree to all" stands apart */
.consent{ margin-top:8px; }
.consent-lead{ margin:0 0 14px; font-size:.9375rem; color:var(--gray-7); }
.consent > .check-err{ margin:2px 0 10px; }      /* what is missing, said on the first box that is not ticked */
.consent .consent-all{ background:transparent; border-color:var(--line-control); }
.consent .consent-all b{ font-weight:600; }
.pay-note{ align-items:center; gap:10px; margin-top:16px; font-size:.875rem; color:var(--gray-7); }
.pay-note svg{ margin-top:0; stroke:var(--silver); }

/* ---- the bottom bar: a message when there is one, the total (opens the breakdown), back, what happens next ---- */
.flow-foot{
  flex-wrap:wrap; justify-content:flex-end; gap:10px 12px;
  padding:14px clamp(20px,3vw,40px) calc(14px + env(safe-area-inset-bottom));
  background:rgba(25,25,28,.86); border-top:1px solid var(--hair);
  backdrop-filter:saturate(180%) blur(20px); -webkit-backdrop-filter:saturate(180%) blur(20px);
}
.flow-foot .flow-error{ flex:1 1 100%; display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; margin:0; }
#flow-error-text{ flex:1 1 200px; min-width:0; }
.flow-retry{ flex:none; }
button.tot{ display:block; min-height:44px; margin-right:auto; padding:0 10px 0 0; border:0; border-radius:10px; background:none; color:inherit; font:inherit; text-align:left; line-height:1.2; cursor:pointer; }
.flow-foot .tot small{ font-size:.8125rem; color:var(--gray-7); }
.flow-foot .tot b{ font-family:var(--font-head); font-size:1.375rem; font-weight:600; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
@media (hover:hover){ button.tot:hover b{ text-decoration:underline; text-decoration-color:var(--line-control); text-underline-offset:4px; } }
.flow-foot #btn-next{ white-space:normal; text-align:center; line-height:1.2; }
/* Review & pay: the pay button is the large one */
#flow[data-step="4"] #btn-next{ min-height:56px; min-width:220px; font-size:1.0625rem; }
/* the bar covers the bottom of every step: scrolling to a field stops short of it */
html{ scroll-padding-bottom:104px; }


/* ================================================================
   43. PHONES (900px and under)
   No panel: the steps use the whole width. The header and the
   bottom bar are the only chrome.
   Design step: ONE top bar (back, the four dots with the current
   step's name, the total, Continue); the editor's own row (undo,
   redo, more) sits beside the heading; the dock owns the bottom, so
   there is no bottom price bar.
   Other steps: the header scrolls up until only the row of labelled
   dots is left; the bottom bar (total + next) is sticky, respects
   the safe area, and steps aside while a text field has focus.
   ================================================================ */
.gd-bar-actions{ display:none; }
@media (max-width:900px){
  .flow-create{ background:none; border:0; border-radius:0; box-shadow:none; overflow:visible; }
  .flow-head{ padding:0; }
  .flow-create .flow-body{ padding:12px 0 24px; }
  .create-main{ padding-top:8px; }
  .fstep[data-step="0"] > h2, .fstep[data-step="0"] > .lead{ text-align:left; margin-inline:0; }
  .fstep > .lead, .opt-main > .lead, .brief > .lead{ margin-bottom:22px; font-size:1rem; }

  /* ---- the header: back and the logo, then the dots in a row of their own ---- */
  .eng-header.create-bar{ position:sticky; top:calc(-1 * var(--header-h)); height:auto; }
  .eng-header.create-bar:has(#progress[hidden]){ top:0; }
  .gd-bar{ display:flex; flex-wrap:wrap; align-items:center; column-gap:8px; height:auto; }
  .gd-bar-nav, .gd-bar-logo{ height:var(--header-h); }
  .gd-bar-nav{ order:1; display:inline-flex; align-items:center; }
  .gd-bar-logo{ order:2; margin-left:auto; }
  .gd-bar-title{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); }
  #progress{ order:5; flex:1 1 100%; align-items:flex-start; padding:2px 0 6px; border-top:1px solid var(--hair); }
  .flow-step{ position:relative; flex:1 1 0; justify-content:center; }
  .flow-step + .flow-step::before{ position:absolute; top:16px; left:calc(-50% + 20px); right:calc(50% + 20px); width:auto; min-width:0; margin:0; }
  .step-btn{ flex-direction:column; gap:5px; width:100%; min-height:50px; padding:8px 2px 4px; border-radius:var(--r-sm); font-size:.75rem; }
  .step-dot{ margin-block:4px; }
  .flow-step.is-done .step-dot{ margin-block:0; }
  .step-n{ display:none; }
  .step-lbl{ max-width:100%; }

  /* ---- Design step: the one top bar ---- */
  body.gd-designing .eng-header.create-bar{ top:0; }
  body.gd-designing .gd-bar{ flex-wrap:nowrap; }
  body.gd-designing .gd-bar-logo{ display:none; }
  body.gd-designing .gd-bar-nav{ flex:none; }
  body.gd-designing .back-link{ padding:0; justify-content:center; gap:0; }
  body.gd-designing .back-link span{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); }
  body.gd-designing .back-link svg{ width:20px; height:20px; }
  body.gd-designing .back-link{ min-width:44px; margin-left:-12px; }
  /* (no room for the hairlines here: the dots sit close together, the current one named) */
  body.gd-designing #progress{ order:2; flex:1 1 auto; gap:7px; min-width:0; align-items:center; padding:0; border-top:0; overflow:hidden; }
  body.gd-designing .flow-step{ flex:0 0 auto; }
  body.gd-designing .flow-step.is-now{ flex:0 1 auto; min-width:0; }
  body.gd-designing .flow-step + .flow-step::before{ display:none; }
  body.gd-designing .step-btn{ flex-direction:row; gap:6px; width:auto; min-width:0; min-height:44px; padding:0; font-size:.8125rem; }
  body.gd-designing .step-dot{ margin-block:0; }
  body.gd-designing .flow-step.is-now .step-dot{ width:20px; }
  body.gd-designing .flow-step:not(.is-now) .step-lbl{ display:none; }
  body.gd-designing .step-n{ display:inline; }
  body.gd-designing .gd-bar-actions{ order:3; display:inline-flex; align-items:center; gap:8px; flex:none; margin-left:auto; }
  /* the running total: a chip that opens the breakdown (which also holds "Change card") */
  .gd-total{
    display:inline-flex; flex-direction:column; align-items:flex-end; justify-content:center; min-height:44px; padding:2px 9px;
    border-radius:var(--r-sm); border:1px solid var(--line-2); background:var(--surface); color:var(--ink); font:inherit; line-height:1.15; cursor:pointer;
  }
  .gd-total small{ font-size:.75rem; color:var(--gray-7); }
  .gd-total b{ font-size:.9375rem; font-weight:600; font-variant-numeric:tabular-nums; }
  /* Continue: the white pill */
  .gd-done{
    display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px; padding:0 18px; border-radius:999px;
    border:1.5px solid #F5F5F7; background:#F5F5F7; color:#000; font:500 .9375rem/1 var(--font-body); letter-spacing:0; white-space:nowrap;
    transition:transform .18s var(--ease), background-color .18s;
  }
  .gd-done:hover{ background:#F5F5F7; }
  .gd-done:active{ transform:scale(.965); background:#D9D9DE; }
  .gd-done.loading{ pointer-events:none; }
  .gd-done.loading::after{ content:""; width:14px; height:14px; border-radius:50%; border:2px solid currentColor; border-right-color:transparent; animation:spin .7s linear infinite; }

  /* ---- Design step: the heading with the editor's own row beside it, then the card ---- */
  .gd-stagewrap{ display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:6px 8px; }
  .design-h{ grid-column:1; grid-row:1; font-size:1.125rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .gd-top{ grid-column:2; grid-row:1; display:flex; flex-wrap:nowrap; align-items:center; gap:2px; margin:0; }
  .gd-top-l{ gap:2px; }
  .gd-top .tb{ width:44px; height:44px; border:0; background:none; border-radius:50%; }
  .gd-top .tb svg{ width:21px; height:21px; }
  .gd-layer{ min-height:44px; padding:0 10px; font-size:.875rem; font-weight:500; }
  .gd-layer.is-single{ display:none; }
  .gd-stagewrap:has(.gd-layer:not(.is-single)) .design-h{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); }
  .gd-stagewrap:has(.gd-layer:not(.is-single)) .gd-top{ grid-column:1 / -1; }
  .gd-stagewrap:has(.gd-layer:not(.is-single)) .gd-layer{ order:-1; margin-right:auto; margin-left:-10px; }
  .gd-stagewrap .ed-stage, .gd-stagewrap .gd-legend{ grid-column:1 / -1; }
  .gd-legend{ margin-top:4px; font-size:.8125rem; }
  .gd-help-link{ min-height:44px; }
  .gd-menu{ right:0; top:calc(100% + 4px); }
  /* the editor's one column may shrink: a tray of three or more designs scrolls inside itself instead of
     widening the column and pushing the card off the screen */
  .ed.gd{ grid-template-columns:minmax(0,1fr); }
  .gd-designs{ grid-template-columns:minmax(0,1fr); }
  /* the tray's small buttons are 44px targets: the name on one line, the three buttons under it */
  .gd-dtile{ flex-basis:140px; }
  .gd-dbar{ flex-wrap:wrap; gap:0; }
  .gd-dbar > span{ flex:1 1 100%; }
  .tb.mini{ width:44px; height:44px; font-size:1.125rem; border:0; background:none; }
  .gd-add{ justify-self:stretch; justify-content:center; }
  /* the dock: on a short screen it leaves the card in view while a tool strip is open */
  .gd-dockwrap{ background:var(--bg-elev); border-top:1px solid var(--hair); }
  .dk{ min-height:64px; }
  /* while a tool strip (font, size, rotate ...) is open the dock shows one row, so the card stays in view */
  .gd-dockwrap:has(#gd-tool:not(.hidden)) .gd-dock{ max-height:76px; }
  .gd-tool input[type=range]{ min-height:44px; }
  .gd-tool .tb, .gd-tool .tb.text{ min-width:44px; min-height:44px; }
  /* draw mode has two buttons: half the dock each, so "Done drawing" stays on one line */
  .dk.wide{ grid-column:span 2; }
  /* an order's design being edited: "Back to my order" and "Save changes" are in the top bar, as Continue is
     on the Design step, and the dock owns the bottom, so the card is never under a bar. The bottom bar comes
     back only while it has something to say (a save that failed, with Retry); it then stands on the dock. */
  body.gd-edit:not(.edit-stopped) .eng-header.create-bar{ top:0; }
  body.gd-edit:not(.edit-stopped) .gd-bar{ flex-wrap:nowrap; }
  body.gd-edit:not(.edit-stopped) .gd-bar-logo{ display:none; }
  body.gd-edit:not(.edit-stopped) .gd-bar-actions{ order:3; display:inline-flex; align-items:center; flex:none; margin-left:auto; }
  body.gd-edit .gd-total{ display:none; }
  body.gd-edit:not(.edit-stopped) .flow-foot{ bottom:var(--dock-h, 0px); }
  body.gd-edit:not(.edit-stopped) .flow-foot:not(.has-msg), body.gd-edit:not(.edit-stopped) .flow-foot > .btn{ display:none; }
  body.gd-edit:not(.edit-stopped) .create-main{ padding-bottom:calc(var(--dock-h, 0px) + 18px); }
  body.gd-edit .create-foot{ display:none; }

  /* ---- the Add sheet ---- */
  .gd-side{ border-radius:var(--r-lg) var(--r-lg) 0 0; background:var(--bg-elev); visibility:hidden; transition:transform .3s var(--ease), visibility 0s .3s; }
  .gd-side.open{ visibility:visible; transition:transform .3s var(--ease); }
  .gd-sheet-head{ height:48px; border-radius:var(--r-lg) var(--r-lg) 0 0; background:var(--bg-elev); }
  .gd-sheet-close{ top:2px; right:6px; width:44px; height:44px; background:none; color:var(--ink); }
  .gd-sheet-close svg{ width:18px; height:18px; }
  .ed-panel .gd-search, .ed-panel .gd-catsrow{ background:var(--bg-elev); }
  .ed-panel .gd-search{ box-shadow:0 -14px 0 0 var(--bg-elev); background:var(--gray-1); }
  .gd-chip{ min-height:44px; }
  .gd-tabs button, .gd-tab-canva{ min-height:56px; }
  /* fade only the trailing edge (a hint that the strip scrolls), with end padding so the last tab can scroll clear of it */
  #gd-tabs.gd-tabs{
    padding-inline-end:28px;
    -webkit-mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent 100%);
    mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent 100%);
  }

  /* ---- Options ---- */
  .np{ padding:16px; gap:12px; }

  /* ---- the bottom bar: edge to edge, above the home indicator, out of the way while typing ---- */
  .flow-foot{
    margin-inline:calc(-1 * var(--pad)); padding:12px var(--pad) calc(12px + env(safe-area-inset-bottom));
    transition:transform .25s var(--ease), visibility 0s;
  }
  .flow-foot .btn{ min-height:var(--control-h); padding:0 22px; font-size:1rem; }
  .flow-foot #btn-next{ flex:1 1 auto; min-width:0; }
  .flow-foot .flow-retry{ min-height:44px; padding:0 16px; font-size:.9375rem; }
  /* Review & pay: the button carries the price, so the total steps aside */
  #flow[data-step="4"] #foot-tot{ display:none; }
  body.typing:not(.gd-edit) .flow-foot{ transform:translateY(110%); visibility:hidden; transition:transform .25s var(--ease), visibility 0s .25s; }
  .create-foot-links{ display:flex; flex-wrap:wrap; justify-content:center; gap:0 20px; margin-top:4px; }
  .create-foot-links .sep{ display:none; }
  .create-foot a{ display:inline-flex; align-items:center; justify-content:center; min-width:44px; min-height:44px; }
}
@media (max-width:560px){
  /* a phone's bar holds the total and one button. Back stays in the header (it walks back a step too);
     an order's design being edited keeps both buttons. */
  body:not(.gd-edit) #flow[data-step="2"] #btn-back, body:not(.gd-edit) #flow[data-step="3"] #btn-back{ display:none; }
  .flow-foot .btn{ padding:0 18px; }
}
@media (max-width:380px){
  /* the narrowest phones: the top bar keeps the step's name without its number */
  body.gd-designing .step-n{ display:none; }
  body.gd-designing #progress{ gap:5px; }
  body.gd-designing .step-btn{ gap:5px; font-size:.75rem; }
  body.gd-designing .gd-bar{ column-gap:6px; }
  body.gd-designing .gd-bar-actions{ gap:6px; }
  .gd-done{ padding:0 13px; font-size:.875rem; }
  .gd-total{ padding:2px 8px; }
  .gd-total b{ font-size:.875rem; }
}
@media (min-width:600px) and (max-width:900px){
  /* a tablet held upright: the dock's buttons in fewer rows, the bar's button its own width */
  .gd-dock{ grid-template-columns:repeat(7,1fr); }
  .flow-foot #btn-next{ flex:0 1 auto; min-width:260px; }
}
@media (max-width:900px) and (max-height:700px){
  .gd-dock{ max-height:30vh; }
}
@media (max-width:360px){
  /* Review: too narrow for label and value side by side */
  .flow-create .rv dl:not(.price-lines){ grid-template-columns:minmax(0,1fr); row-gap:2px; }
  .flow-create .rv dd + dt{ margin-top:10px; }
}
@media (prefers-reduced-motion:reduce){
  .gd-side, .gd-side.open, .flow-foot, .gd-done{ transition:none; }
  .gd-done:active{ transform:none; }
}


/* ================================================================
   44. DIALOGS, SHEETS, TOAST
   The price line by line, the preview, Free Design Help. create.js
   keeps the keyboard inside the open one, closes it on Escape and
   hands focus back to what opened it.
   ================================================================ */
.fb-wrap, .gd-preview{ background:rgba(10,10,12,.72); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); }
.fb-card, .gd-preview-card{
  background:var(--bg-elev); border:1px solid var(--line-2); border-radius:var(--r-lg);
  box-shadow:0 40px 100px rgba(0,0,0,.6); padding:28px 24px 24px;
}
.fb-card h2, .gd-preview-card h2{ margin:0 44px 8px 0; font-size:1.5rem; line-height:1.15; letter-spacing:-.02em; }
.gd-preview-card h2{ margin-right:0; }
.gd-preview-card .mono-label{ display:block; margin:0 0 8px; font:600 .8125rem/1.3 var(--font-body); letter-spacing:.06em; text-transform:uppercase; color:var(--accent-text); }
.fb-sub, .gd-preview-note{ font-size:.9375rem; color:var(--gray-7); }
.fb-actions, .gd-preview-actions{ gap:10px; margin-top:10px; }
.pv-x{
  top:10px; right:10px; width:44px; height:44px; display:grid; place-items:center; border:0; border-radius:50%;
  background:rgba(255,255,255,.08); color:var(--ink); font-size:1.4rem; line-height:1;
}
@media (hover:hover){ .pv-x:hover{ background:rgba(255,255,255,.16); } }
.gd-preview-stage{ border-radius:var(--r); }
.price-sheet-card{ width:min(100%, 460px); }
.price-sheet-card .price-lines{ margin-top:8px; }
.price-sheet-note{ margin:14px 0 18px; font-size:.875rem; line-height:1.5; color:var(--gray-7); }
@media (min-width:900.02px){ .gd-preview{ z-index:60; } }
@media (max-width:640px){
  /* on a phone a dialog is a sheet from the bottom edge */
  .fb-wrap, .gd-preview{ place-items:end center; padding:0; }
  .fb-card, .gd-preview-card{
    width:100%; max-height:92dvh; border-radius:var(--r-lg) var(--r-lg) 0 0; border-bottom:0;
    padding:24px var(--pad) calc(20px + env(safe-area-inset-bottom));
    animation:sheet-up .3s var(--ease);
  }
  .fb-actions .btn, .gd-preview-actions .btn{ flex:1 1 auto; }
}
@keyframes sheet-up{ from{ transform:translateY(24px); opacity:0; } to{ transform:none; opacity:1; } }

/* "All changes saved": a small pill with a tick, clear of the dock on phones and of the bottom bar on wide screens */
.gd-toast{
  display:inline-flex; align-items:center; gap:8px; padding:10px 16px 10px 12px; border-radius:999px;
  background:var(--gray-1); border:1px solid var(--line-2); color:var(--ink); font:500 .875rem/1.2 var(--font-body);
  box-shadow:0 14px 34px rgba(0,0,0,.5); white-space:nowrap;
}
.gd-toast::before{
  content:""; flex:none; width:18px; height:18px; border-radius:50%;
  background:var(--ok) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23141416' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 12.5l4.2 4.2L18.5 8'/%3E%3C/svg%3E") center/11px no-repeat;
}
/* a wide screen: under the header, where nothing is; at the bottom it would lie on the dock */
@media (min-width:900.02px){ .gd-toast{ top:calc(var(--header-h) + 12px); bottom:auto; transform:translate(-50%, -8px); } .gd-toast.show{ transform:translate(-50%, 0); } }
@media (prefers-reduced-motion:reduce){ .fb-card, .gd-preview-card{ animation:none; } .gd-toast{ transition:none; } }


/* ================================================================
   45. LOADING AND EMPTY STATES
   ================================================================ */
/* until create.js knows which step the visit starts on: a quiet spinner, the size of a step,
   so the page does not jump when the step takes its place */
.flow-boot{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
  min-height:min(64vh, 620px); margin:0; text-align:center; font-size:.9375rem; color:var(--gray-7);
}
.flow-boot::before{
  content:""; width:22px; height:22px; border-radius:50%; border:2px solid var(--line-control); border-top-color:var(--ink);
  animation:spin .8s linear infinite;
}
/* a visit that opens on the editor or a later step: the placeholder fills the screen, as the step will,
   so the bottom bar is already where it stays */
html:not([data-boot="s0"]) .flow-boot{ min-height:calc(100vh - 200px); }
/* said only when the page has been loading for a while */
.flow-boot-late{ max-width:36ch; opacity:0; animation:boot-late 0s 8s forwards; }
@keyframes boot-late{ to{ opacity:1; } }
@media (prefers-reduced-motion:reduce){ .flow-boot::before{ animation:none; } }
/* a template being put on the card, an upload being read */
.gd-tile.loading{ opacity:.5; pointer-events:none; cursor:progress; }
.gd-upload-btn.loading{ cursor:progress; }
/* nothing found, nothing yet */
.gd-empty-note{ padding:18px 4px; text-align:center; font-size:.875rem; color:var(--gray-7); }
/* the editor could not start: only its message stays, with the way to hand the design to us */
body.no-editor .gd-top, body.no-editor .gd-legend, body.no-editor .gd-dockwrap, body.no-editor .gd-designs, body.no-editor .gd-side{ display:none; }
body.no-editor .gd .ed-stage{ aspect-ratio:auto; min-height:180px; border-radius:var(--r); border:1px dashed var(--line-control); background:var(--surface); }
body.no-editor .ed-empty{ position:static; padding:28px 20px; }

/* ================================================================
   46. EXPLAIN YOUR DESIGN (the Design step of a new order)
   The card in the middle of the page, the text box under it. "Add"
   stands at the card's right; with more than one card the others
   wait at the sides, turned away, and the arrows bring them back.
   ================================================================ */
.xd{ display:grid; justify-items:center; gap:18px; max-width:760px; margin-inline:auto; text-align:center; }
.xd > h2{ margin:0; }
.xd-stage{
  display:grid; grid-template-columns:minmax(52px,1fr) minmax(0,440px) minmax(52px,1fr); align-items:center; gap:10px;
  width:100%; padding-block:14px; overflow:hidden; overflow:clip;      /* the cards at the sides are cut at the page's edge, never widen it */
}
.xd-cell{ position:relative; z-index:5; display:grid; gap:12px; justify-items:center; }
.xd-cell-l{ justify-self:end; } .xd-cell-r{ justify-self:start; }
.xd-deck{ position:relative; width:100%; aspect-ratio:1013 / 638; perspective:1100px; }
.xd-card{
  position:absolute; top:0; left:0; width:100%; height:100%; padding:0; overflow:hidden; cursor:default;
  border:0; border-radius:4.2% / 6.6%; color:var(--gray-5);
  background:linear-gradient(125deg, rgba(255,255,255,.13), rgba(255,255,255,.02) 50%, rgba(255,255,255,.08)), #0d0d0f;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 0 0 1px rgba(255,255,255,.2), 0 30px 50px -28px rgba(0,0,0,.9);
  opacity:0; pointer-events:none; transform:translateX(0) scale(.5);
  transition:transform .6s cubic-bezier(.22,.61,.36,1), opacity .45s;
}
.xd-card-n{ position:absolute; left:6%; bottom:8%; font-size:.75rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase; }
/* where a card stands: 0 in the middle, -1 / 1 beside it, the rest further out and fainter */
.xd-card[data-pos="0"]{ opacity:1; transform:none; z-index:4; }
.xd-card[data-pos="-1"]{ opacity:.75; transform:translateX(-64%) rotateY(46deg) scale(.74); z-index:3; pointer-events:auto; cursor:pointer; }
.xd-card[data-pos="1"]{ opacity:.75; transform:translateX(64%) rotateY(-46deg) scale(.74); z-index:3; pointer-events:auto; cursor:pointer; }
.xd-card[data-pos="-2"],.xd-card[data-pos="-3"]{ opacity:.35; transform:translateX(-98%) rotateY(56deg) scale(.58); z-index:2; }
.xd-card[data-pos="2"],.xd-card[data-pos="3"]{ opacity:.35; transform:translateX(98%) rotateY(-56deg) scale(.58); z-index:2; }
/* a card that was just added starts edge-on at the right and turns to face you */
.xd-card[data-pos="new"]{ opacity:0; transform:translateX(70%) rotateY(-100deg) scale(.8); transition:none; z-index:4; }
.xd-stage:has(.xd-card:only-child) .xd-card-n{ display:none; }  /* a single card needs no number */

.xd-arrow{
  display:grid; place-items:center; width:44px; height:44px; padding:0; border-radius:50%; cursor:pointer;
  border:1.5px solid var(--line-control); background:rgba(20,20,22,.7); color:var(--ink);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  transition:transform .18s var(--ease), background-color .18s, border-color .18s;
}
.xd-arrow svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
@media (hover:hover){ .xd-arrow:hover{ background:rgba(255,255,255,.1); border-color:rgba(255,255,255,.6); } }
.xd-arrow:active,.xd-add:active .xd-add-ico{ transform:scale(.92); }
.xd-add{
  display:grid; justify-items:center; gap:6px; padding:0; border:0; background:none; cursor:pointer;
  font:600 .8125rem/1.2 var(--font-body); color:var(--ink); -webkit-tap-highlight-color:transparent;
}
.xd-add-ico{
  display:grid; place-items:center; width:48px; height:48px; border-radius:50%; background:#F5F5F7; color:#000;
  transition:transform .18s var(--ease), background-color .18s;
}
.xd-add-ico svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; }
@media (hover:hover){ .xd-add:hover .xd-add-ico{ background:#FFFFFF; } }
.xd-arrow:focus-visible,.xd-add:focus-visible{ outline:2px solid var(--focus); outline-offset:3px; border-radius:50%; }
.xd-add:focus-visible{ border-radius:12px; }

.xd-count{ min-height:24px; margin:-6px 0 0; font-size:.9375rem; color:var(--gray-7); }
.xd-count.is-one{ display:none; }
.xd-count .link-btn{ margin-left:10px; }
.xd-field{ width:100%; max-width:560px; margin:0; text-align:left; }
.xd-field > span:first-child{ font-size:1.0625rem; font-weight:600; letter-spacing:-.01em; text-align:center; }
.xd-field textarea{ min-height:132px; }
.xd-ref{ width:100%; max-width:560px; text-align:left; }
.xd-note{ max-width:52ch; margin:0; font-size:.875rem; line-height:1.5; color:var(--gray-7); }
@media (max-width:520px){
  .xd-stage{ grid-template-columns:48px minmax(0,1fr) 48px; gap:6px; }
  .xd-arrow{ width:40px; height:40px; }
  .xd-add-ico{ width:44px; height:44px; }
}
@media (prefers-reduced-motion:reduce){
  .xd-card,.xd-arrow,.xd-add-ico{ transition:none; }
}

/* ---- the preview of a design: its picture on the card, the button under the text box, the loader ---- */
.xd-card-art{ position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; display:none; }
.xd-card.has-art .xd-card-art{ display:block; }
.xd-card.has-art .xd-card-n{ padding:3px 8px; border-radius:999px; background:rgba(10,10,11,.7); color:#F5F5F7; }
.xd-gen{ display:grid; justify-items:center; gap:8px; width:100%; max-width:560px; margin-top:-4px; }
.xd-gen-note{ margin:0; font-size:.875rem; color:var(--gray-7); }
.xd-save{ gap:8px; }
.xd-save svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.xd-save[hidden]{ display:none; }
/* a question with two answers, over the page */
.yn{ position:fixed; inset:0; z-index:400; display:grid; place-items:center; padding:20px; background:rgba(0,0,0,.66); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); }
.yn[hidden]{ display:none; }
.yn-box{ width:100%; max-width:400px; padding:24px; border-radius:var(--r); background:var(--surface); border:1px solid var(--line-2); box-shadow:0 24px 80px rgba(0,0,0,.6); text-align:center; }
.yn-box h2{ margin:0; font-size:1.25rem; letter-spacing:-.01em; }
.yn-box p{ margin:10px 0 0; font-size:.9375rem; line-height:1.5; color:var(--gray-7); }
.yn-btns{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:20px; }
.yn-btns .btn{ width:100%; }
.xd-gen-msg{ max-width:560px; margin:0; padding:12px 16px; border-radius:var(--r-sm); border:1px solid var(--line-2); background:var(--gray-1); font-size:.9375rem; line-height:1.5; text-align:left; color:var(--ink); }
/* the loader: over the card in the middle, our own designs one after another, dimmed, under the words */
.xd-load{
  position:absolute; top:0; left:0; width:100%; height:100%; z-index:6; overflow:hidden;
  border-radius:4.2% / 6.6%; background:#0b0b0d; box-shadow:0 0 0 1px rgba(255,255,255,.2);
}
.xd-load img{ position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .7s; }
.xd-load img.on{ opacity:.5; }
.xd-load.is-line img{ filter:invert(1) grayscale(1) contrast(1.05); }      /* the templates are black line art on white */
.xd-load::after{                                                           /* a band of light that sweeps across */
  content:""; position:absolute; top:0; bottom:0; left:-60%; width:60%;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,.16), transparent); animation:xd-sweep 1.8s linear infinite;
}
/* the loading film: over the pictures once it plays (create.js adds .has-video) */
.xd-load-video{ position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .4s; }
.xd-load.has-video .xd-load-video{ opacity:1; }
.xd-load.has-video img{ display:none; }
.xd-load.has-video::after{ display:none; }
/* the film has its own card and its own word "LOADING": our words step aside (still read out) and the bar sits at the foot, over the film's line */
.xd-load.has-video .xd-load-box{ top:auto; bottom:5%; transform:translateX(-50%); }
.xd-load.has-video .xd-load-text{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); padding:0; border:0; }
/* the words, and under them the bar and its percentage */
.xd-load-box{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:1; display:grid; justify-items:center; gap:10px; width:min(78%, 320px); }
.xd-load-row{
  display:flex; align-items:center; gap:10px; width:100%; padding:8px 12px; border-radius:999px;
  background:rgba(10,10,11,.78); border:1px solid rgba(255,255,255,.22); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
.xd-load-bar{ flex:1; height:8px; border-radius:999px; overflow:hidden; background:rgba(255,255,255,.2); }
.xd-load-fill{ display:block; width:0; height:100%; border-radius:999px; background:#F5F5F7; transition:width .25s linear; }
.xd-load-pct{ flex:none; min-width:3.2ch; text-align:right; font-size:.875rem; font-weight:600; font-variant-numeric:tabular-nums; color:#F5F5F7; }
.xd-load-text{
  display:flex; align-items:baseline; gap:2px;
  margin:0; padding:10px 18px; border-radius:999px; white-space:nowrap;
  background:rgba(10,10,11,.78); border:1px solid rgba(255,255,255,.22); -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  font-size:1rem; font-weight:600; letter-spacing:-.01em; color:#F5F5F7;
}
.xd-load-dots{ display:inline-flex; gap:3px; margin-left:4px; }
.xd-load-dots i{ width:4px; height:4px; border-radius:50%; background:currentColor; animation:xd-dot 1.2s infinite both; }
.xd-load-dots i:nth-child(2){ animation-delay:.2s; } .xd-load-dots i:nth-child(3){ animation-delay:.4s; }
@keyframes xd-sweep{ to{ left:120%; } }
@keyframes xd-dot{ 0%,80%,100%{ opacity:.25; } 40%{ opacity:1; } }
@media (max-width:520px){ .xd-load-text{ font-size:.875rem; padding:8px 14px; } .xd-load-box{ gap:6px; } .xd-load-row{ padding:6px 10px; } }
@media (prefers-reduced-motion:reduce){
  .xd-load img{ transition:none; } .xd-load::after{ animation:none; display:none; } .xd-load-dots i{ animation:none; opacity:.7; }
}

/* ================================================================
   47. THE THREE WAYS TO DESIGN (#mode-bar)
   Three icons in a row, each with its name under it; the one in use
   is filled. They stay at the top of the Design step, so changing
   from one to another is one tap.
   ================================================================ */
.mode-bar{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; width:100%; max-width:560px; margin:0 auto 22px; padding:6px;
  border-radius:22px; background:var(--surface); border:1px solid var(--line-2);
}
.mode-bar button{
  display:grid; justify-items:center; align-content:center; gap:7px; min-height:84px; padding:10px 6px; border:0; border-radius:16px;
  background:transparent; color:var(--gray-7); cursor:pointer; -webkit-tap-highlight-color:transparent;
  transition:background-color .18s, color .18s, transform .18s var(--ease);
}
.mode-ico{ display:grid; place-items:center; width:40px; height:40px; border-radius:50%; background:rgba(255,255,255,.07); transition:background-color .18s, color .18s; }
.mode-ico svg{ width:21px; height:21px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.mode-name{ font-size:.875rem; font-weight:600; line-height:1.2; letter-spacing:-.005em; text-align:center; }
@media (hover:hover){ .mode-bar button:not(.on):hover{ background:rgba(255,255,255,.05); color:var(--ink); } }
.mode-bar button:active{ transform:scale(.97); }
.mode-bar button.on{ background:var(--gray-1); color:var(--ink); box-shadow:inset 0 0 0 1.5px var(--ring); }
.mode-bar button.on .mode-ico{ background:#F5F5F7; color:#000; }
.mode-bar button:focus-visible{ outline:2px solid var(--focus); outline-offset:2px; }
@media (max-width:420px){
  .mode-bar{ gap:4px; padding:4px; margin-bottom:16px; }
  .mode-bar button{ min-height:76px; padding:8px 2px; }
  .mode-name{ font-size:.8125rem; }
}
@media (prefers-reduced-motion:reduce){ .mode-bar button,.mode-ico{ transition:none; } .mode-bar button:active{ transform:none; } }

/* Upload photo: the editor with only its upload tools. The starting points and the other tabs are put away,
   whatever the editor's own state says (hence !important). */
body[data-mode="upload"] #gd-start,
body[data-mode="upload"] .gd-tabsrow,
body[data-mode="upload"] .ed-panel:not(#gd-panel-upload){ display:none !important; }
body[data-mode="upload"] #gd-panel-upload{ display:block !important; }
/* the hint on an empty card says what this way does */
.ed-empty .for-upload{ display:none; }
body[data-mode="upload"] .ed-empty .for-upload{ display:inline; }
body[data-mode="upload"] .ed-empty .for-tools{ display:none; }

/* the starting points are one word each (Template, Text, Icon, Canva): the word sits level with its icon */
.gd-choice--word{ align-items:center; }
.gd-choice--word b{ font-size:1.0625rem; }

/* the "?" beside the upload button: a round button that opens a small note under the row */
.gd-upload-row{ display:flex; align-items:center; gap:10px; }
.gd-upload-row .gd-upload-btn{ flex:1 1 auto; margin:0; white-space:nowrap; }
.gd-q{
  flex:none; display:grid; place-items:center; width:44px; height:44px; padding:0; border-radius:50%; cursor:pointer;
  border:1.5px solid var(--line-control); background:transparent; color:var(--ink); font:600 1.0625rem/1 var(--font-body);
  transition:background-color .18s, border-color .18s, color .18s;
}
@media (hover:hover){ .gd-q:hover{ background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.6); } }
.gd-q[aria-expanded="true"]{ background:#F5F5F7; border-color:#F5F5F7; color:#000; }
.gd-q:focus-visible{ outline:2px solid var(--focus); outline-offset:3px; }
.gd-q-pop{
  margin:10px 0 0; padding:14px 16px; border-radius:var(--r-sm); background:var(--gray-1); border:1px solid var(--line-2);
  font-size:.875rem; line-height:1.5; text-align:left; color:var(--ink);
}

/* ================================================================
   48. THE GROUND AROUND THE CARD
   The card is black and (on either card now) plain, so it sits on
   gray: in the editor's panel, and behind the cards of AI Designs.
   ================================================================ */
:root{ --card-ground:#55555C; }
@media (min-width:900.02px){
  .gd-stagewrap{
    background-color:var(--card-ground);
    background-image:radial-gradient(circle, rgba(255,255,255,.1) 1px, transparent 1.5px);
    border-color:rgba(255,255,255,.14);
  }
}
/* phones: the editor has no panel, so the card gets a gray frame of its own */
@media (max-width:900px){
  .gd .ed-stage{ margin:10px; border-radius:10px; background:var(--card-ground); box-shadow:0 0 0 10px var(--card-ground); }
}
/* what is written on the gray stays readable */
.gd-stagewrap .gd-legend{ color:#EDEDF0; }
.gd-stagewrap .gd-legend .sw.black{ border-color:rgba(255,255,255,.6); }
.gd .ed-empty span{ color:#C7C7CC; }
.xd-stage{ padding:22px 10px; border-radius:var(--r-lg); background:var(--card-ground); }
.xd-stage .xd-add{ color:#FFFFFF; }
.xd-stage .xd-arrow{ background:rgba(20,20,22,.78); border-color:rgba(255,255,255,.6); }

/* the drop box under the upload button: several images at once */
.gd-dropbox{
  display:grid; justify-items:center; gap:4px; margin-top:12px; padding:22px 14px; text-align:center; cursor:pointer;
  border:1.5px dashed var(--line-control); border-radius:var(--r); background:rgba(255,255,255,.03); color:var(--gray-7);
  transition:border-color .18s, background-color .18s, color .18s;
}
.gd-dropbox svg{ width:28px; height:28px; margin-bottom:4px; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.gd-dropbox b{ font-size:.9375rem; font-weight:600; color:var(--ink); }
.gd-dropbox small{ font-size:.8125rem; }
@media (hover:hover){ .gd-dropbox:hover{ border-color:rgba(255,255,255,.6); background:rgba(255,255,255,.06); } }
.gd-dropbox.is-over{ border-style:solid; border-color:#F5F5F7; background:rgba(255,255,255,.1); color:var(--ink); }
.gd-dropbox.loading{ opacity:.6; pointer-events:none; cursor:progress; }
.gd-uploads{ margin-top:16px; }
.gd-uploads-hint{ margin-left:6px; font-weight:400; color:var(--gray-5); }

/* the two keys in the "more" menu, one under the other */
.gd-menu-note{ display:grid; gap:8px; }
.gd-menu-note > span{ display:flex; align-items:center; gap:8px; }

/* the hint on an empty card darkens the card's lower half: it takes the card's own corners (editor.js CORNER,
   0.125 in on a 3.37 in card), or its square corners show under the card's round ones */
.gd .ed-empty{ border-radius:3.71% / 5.89%; }

/* ================================================================
   49. OPTIONS ON A PHONE: THE ORDER OF ITS PARTS
   One column, in this order: the card · the engraving color · where
   the card comes from (Tesla) or the link it opens (NFC) · how many
   cards · the price. The two columns of the wide layout are dissolved
   (display:contents) so their parts can be put in that order.
   ================================================================ */
@media (max-width:900px){
  .opt-cols{ display:flex; flex-direction:column; }
  .opt-main, .opt-side{ display:contents; }
  #cards-show{ order:1; margin-top:0; }
  #color-field{ order:2; margin-top:20px; }
  #card-h, #card-lead{ order:3; }
  #card-h:not(.sr-only){ margin-top:28px; }
  #nfc-block, #src-block{ order:4; }
  #src-block{ margin-top:24px; }
  #qty-h{ order:5; }
  #cards-box{ order:6; }
  #price-h{ order:7; margin-top:28px; }
  #totals{ order:8; }
  #ship-note{ order:9; }
}

/* Tools & Templates has no Uploads tab: uploading is its own way in (Upload photo) */
body[data-mode="tools"] .ed-tabs [data-tab="upload"],
body[data-mode="tools"] #gd-panel-upload{ display:none !important; }

/* ================================================================
   50. TEMPLATES: THE CAROUSEL (#tpl-show)
   A large dialog over the page: the heading, the 3D cards on the
   concrete wall of the old homepage, the arrows and dots, the name of
   the design in front, and "Use this design".
   ================================================================ */
.tpl-show{ padding:12px; }
.tpl-show-card{
  position:relative; display:grid; justify-items:center; gap:14px; width:min(100%, 1040px); max-height:100%; overflow:auto;
  padding:clamp(20px,4vw,36px) clamp(12px,3vw,32px) clamp(18px,3vw,28px); border-radius:var(--r-lg); color:var(--ink);
  background:#0A0A0B url(/assets/images/hero-backdrop.jpg) center bottom / cover no-repeat; border:1px solid rgba(255,255,255,.14);
  box-shadow:0 40px 90px -30px rgba(0,0,0,.9);
}
.tpl-show-card h2{ margin:0; font-size:clamp(1.5rem,2vw + 1rem,2.25rem); letter-spacing:-.025em; text-align:center; text-shadow:0 1px 2px rgba(0,0,0,.55), 0 2px 10px rgba(0,0,0,.35); }
.tpl-3d.hero-3d.showcase{ width:100%; aspect-ratio:21 / 9; max-height:min(46vh, 440px); }
.tpl-3d-wait{ margin:0; font-size:.9375rem; color:var(--gray-3); }
.tpl-show .show-nav{ margin:0; }
.tpl-show .dots{ max-width:min(60vw, 420px); gap:7px; }
.tpl-show .nav-arrow{ width:44px; height:44px; }
.tpl-show .hero-caption{ margin:0; min-height:3em; text-shadow:0 2px 10px rgba(0,0,0,.8); }
.tpl-show .hero-caption b{ color:#FFFFFF; }
.tpl-show .hero-caption span{ display:block; }
.tpl-actions{ display:flex; justify-content:center; }
.tpl-actions .btn svg{ width:18px; height:18px; margin-left:8px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.gd-tpl-open{ width:100%; gap:10px; }
.gd-tpl-open svg{ width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
/* without WebGL: the designs as a plain grid to pick from */
.tpl-3d.is-list{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px; aspect-ratio:auto; max-height:56vh; overflow:auto; place-items:stretch; }
.tpl-flat{ display:grid; gap:6px; padding:8px; border-radius:var(--r-sm); border:1px solid var(--line-2); background:rgba(20,20,22,.85); color:var(--ink); font-size:.8125rem; cursor:pointer; }
.tpl-flat img{ width:100%; height:auto; border-radius:6px; filter:invert(1) grayscale(1) contrast(1.05); }
@media (max-width:640px){
  .tpl-3d.hero-3d.showcase{ aspect-ratio:4 / 3; max-height:38vh; }
  .tpl-show .dots{ max-width:70vw; }
  .tpl-actions .btn{ width:100%; }
  .tpl-actions{ width:100%; }
}

.tpl-3d .card3d-canvas{
  /* the renderer paints a soft glow behind the cards that is larger than this box: without a feather
     it stops on a straight line at the box's edges (seen as a dark band ending under the title) */
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 22%, #000 80%, transparent 100%);
  mask-image:linear-gradient(180deg, transparent 0%, #000 22%, #000 80%, transparent 100%);
}

/* the S3XY Profile block at the top of Details */
.pf-block{ margin-bottom:8px; }
.pf-in{ margin:0 0 8px; font-size:1rem; color:var(--gray-7); }
.pf-in b{ color:var(--ink); overflow-wrap:anywhere; }
.pf-in .link-btn{ margin-left:10px; }
#pf-fields[hidden],#pf-in[hidden],.pf-block[hidden]{ display:none; }
