/* Feature: the honest print configurator (vision §E3.4, §D9, §D18–§D20, §D28, §F3, §G3).
   Markup: js/v3/features/configurator/{index,panel,preview,pictures}.js. Loaded by the page that
   mounts it (<link rel="stylesheet" href="/css/v3/features/configurator.css">) or added once by
   the module before it renders anything.

   The Lamp is off in here: no pool, no light, no shadows on the previews; the surround is the
   achromatic --proof grey and the picture shows in true colour (vision §A, §B1, §B3).
   Layout follows the space it is given (container queries): one column in the painting page's
   panel (300–500 px), the sheet or a phone; preview beside the options from 880 px. */

/* The print area and the front of the print, as fractions of the photo (set by preview.js).
   Registered so a size change slides the trim instead of jumping (instant in Calm). */
@property --rx0 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --ry0 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --rx1 { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --ry1 { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --fx0 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --fy0 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --fx1 { syntax: "<number>"; inherits: true; initial-value: 1; }
@property --fy1 { syntax: "<number>"; inherits: true; initial-value: 1; }

@layer pages {
  /* ------------------------------------------------------------------ root, inline section */
  .cfg {
    --pool: transparent; /* the lamp is off while buying */
    display: grid;
    gap: var(--space-5);
    min-inline-size: 0;
  }
  .cfg__title { margin: 0; }
  .cfg__slot { min-inline-size: 0; }
  .cfg__slot:empty { display: none; }

  /* ------------------------------------------------------------------ the panel */
  .cfg-panel {
    --pool: transparent;
    --proof-ink: light-dark(#474747, #c9c9c9); /* 6.5:1 on #dedede, 7.5:1 on #333 */
    --proof-line: light-dark(rgb(0 0 0 / 0.42), rgb(255 255 255 / 0.5));
    container: cfg-panel / inline-size;
    min-inline-size: 0;
  }
  .cfg-panel__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
    align-items: start;
  }
  .cfg-panel__view, .cfg-panel__options { min-inline-size: 0; }
  .cfg-panel__options {
    container: cfg-options / inline-size;
    display: grid;
    gap: var(--space-6);
  }

  @container cfg-panel (min-width: 880px) {
    .cfg-panel__inner {
      grid-template-columns: minmax(0, 1.25fr) minmax(340px, 1fr);
      column-gap: clamp(36px, 5cqi, 80px);
    }
    /* The preview stays in view while the options scroll past (it is never taller than the screen). */
    .cfg-panel__view {
      position: sticky;
      inset-block-start: calc(var(--sticky-top) + var(--space-4));
    }
    /* Beside the preview, the size note need not repeat the trim sentence under it. */
    .cfg-field__note--trim { display: none; }
  }

  /* ------------------------------------------------------------------ docked preview
     Painting page, desktop, one-column panel (panel.js createDock): once the full preview has
     scrolled away, a compact copy stays at the top of the column while the choices scroll under
     it, so the framed or canvas print is in view while the visitor picks it. The lamp is off in
     here: a flat sheet on --raised, no pool, no shadow. */
  .cfg-panel[data-docked] .cfg-panel__view {
    position: sticky;
    inset-block-start: calc(var(--sticky-top) + var(--space-4));
    z-index: 2;
    padding: var(--space-2) var(--space-3) var(--space-3);
    margin-inline: calc(-1 * var(--space-3));
    background: var(--raised);
    border: 1px solid var(--rule);
    animation: cfg-dock var(--dur-settle) var(--ease-set) both;
  }
  .cfg-panel[data-docked] .cfg-tabpanel { padding-block-start: var(--space-3); }
  .cfg-panel[data-docked] .cfg-stage { max-block-size: max(200px, 34svh); min-block-size: 200px; }
  .cfg-panel[data-docked] .cfg-caption { padding-block-start: var(--space-3); }
  .cfg-panel[data-docked] .cfg-caption > :not(.cfg-caption__lead) { display: none; }
  @keyframes cfg-dock { from { opacity: 0; } }

  /* ------------------------------------------------------------------ preview tabs */
  .cfg-tabs__list { column-gap: var(--space-5); }
  .cfg-tabpanel { padding-block-start: var(--space-4); }
  .cfg-tabpanel:focus-visible { outline-offset: 4px; }

  .cfg-figure { display: grid; gap: 0; margin: 0; }

  /* The stage: a size container, so everything inside scales with cq units and nothing moves when
     the size or the format changes. Portrait and square work sits in a square, landscape in 4:3. */
  .cfg-stage {
    position: relative;
    container-type: size;
    inline-size: 100%;
    aspect-ratio: 1 / 1;
    max-block-size: min(62svh, 600px);
    min-block-size: 240px;
    overflow: hidden;
    background: var(--proof);
  }
  .cfg-tabs[data-orient="landscape"] .cfg-stage { aspect-ratio: 4 / 3; }
  @container cfg-panel (min-width: 520px) {
    .cfg-stage { aspect-ratio: 5 / 4; }
    .cfg-tabs[data-orient="landscape"] .cfg-stage { aspect-ratio: 3 / 2; }
  }
  @container cfg-panel (min-width: 880px) {
    .cfg-stage { max-block-size: max(320px, 100svh - var(--header-h) - 280px); }
  }
  .cfg-panel[data-context="sheet"] .cfg-stage { max-block-size: min(44svh, 520px); }
  .cfg-panel[data-context="dialog"] .cfg-stage { max-block-size: min(44svh, 520px); }
  @container cfg-panel (min-width: 880px) {
    .cfg-panel[data-context="dialog"] .cfg-stage { max-block-size: min(100svh - 330px, 560px); }
  }

  /* ------------------------------------------------------------------ What prints */
  .cfg-stage--proof { display: grid; place-items: center; }
  .cfg-proof {
    --pad-x: clamp(30px, 9cqi, 64px);
    --pad-y: clamp(30px, 8.5cqb, 56px);
    position: relative;
    inline-size: min(100cqi - 2 * var(--pad-x), (100cqb - 2 * var(--pad-y)) * var(--img-ar, 1));
    aspect-ratio: var(--img-ar, 1);
    transition:
      --rx0 var(--dur-settle) var(--ease-set), --rx1 var(--dur-settle) var(--ease-set),
      --ry0 var(--dur-settle) var(--ease-set), --ry1 var(--dur-settle) var(--ease-set),
      --fx0 var(--dur-settle) var(--ease-set), --fx1 var(--dur-settle) var(--ease-set),
      --fy0 var(--dur-settle) var(--ease-set), --fy1 var(--dur-settle) var(--ease-set);
  }
  .cfg-proof__img {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    max-inline-size: none;
    -webkit-user-drag: none;
    user-select: none;
  }

  /* What the lab trims: 70% proof grey over the photo (the trim preview is the one place marks
     may sit on the picture, vision §I). */
  .cfg-proof__dim {
    position: absolute;
    background: color-mix(in srgb, var(--proof) 70%, transparent);
    pointer-events: none;
  }
  .cfg-proof__dim--l { top: 0; bottom: 0; left: 0; width: calc(var(--rx0) * 100%); }
  .cfg-proof__dim--r { top: 0; bottom: 0; right: 0; width: calc((1 - var(--rx1)) * 100%); }
  .cfg-proof__dim--t { top: 0; left: calc(var(--rx0) * 100%); right: calc((1 - var(--rx1)) * 100%); height: calc(var(--ry0) * 100%); }
  .cfg-proof__dim--b { bottom: 0; left: calc(var(--rx0) * 100%); right: calc((1 - var(--rx1)) * 100%); height: calc((1 - var(--ry1)) * 100%); }

  /* The edge of the print: white dashes over a dark hairline, legible on any picture. */
  .cfg-proof__edge {
    position: absolute;
    top: calc(var(--ry0) * 100%);
    bottom: calc((1 - var(--ry1)) * 100%);
    left: calc(var(--rx0) * 100%);
    right: calc((1 - var(--rx1)) * 100%);
    border: 1px dashed rgb(255 255 255 / 0.92);
    outline: 1px solid rgb(0 0 0 / 0.38);
    pointer-events: none;
  }

  /* Image wrap: the band that folds round the sides, hatched, and the fold itself dotted. */
  .cfg-proof__wrap, .cfg-proof__fold { display: none; position: absolute; pointer-events: none; }
  .cfg-proof[data-wrap="image"] :is(.cfg-proof__wrap, .cfg-proof__fold) { display: block; }
  .cfg-proof__wrap {
    background:
      repeating-linear-gradient(135deg, rgb(255 255 255 / 0.42) 0 1px, rgb(0 0 0 / 0.2) 1px 2px, transparent 2px 9px),
      rgb(0 0 0 / 0.08);
  }
  .cfg-proof__wrap--l { top: calc(var(--ry0) * 100%); bottom: calc((1 - var(--ry1)) * 100%); left: calc(var(--rx0) * 100%); width: calc((var(--fx0) - var(--rx0)) * 100%); }
  .cfg-proof__wrap--r { top: calc(var(--ry0) * 100%); bottom: calc((1 - var(--ry1)) * 100%); right: calc((1 - var(--rx1)) * 100%); width: calc((var(--rx1) - var(--fx1)) * 100%); }
  .cfg-proof__wrap--t { left: calc(var(--fx0) * 100%); right: calc((1 - var(--fx1)) * 100%); top: calc(var(--ry0) * 100%); height: calc((var(--fy0) - var(--ry0)) * 100%); }
  .cfg-proof__wrap--b { left: calc(var(--fx0) * 100%); right: calc((1 - var(--fx1)) * 100%); bottom: calc((1 - var(--ry1)) * 100%); height: calc((var(--ry1) - var(--fy1)) * 100%); }
  .cfg-proof__fold {
    top: calc(var(--fy0) * 100%);
    bottom: calc((1 - var(--fy1)) * 100%);
    left: calc(var(--fx0) * 100%);
    right: calc((1 - var(--fx1)) * 100%);
    border: 1px dotted rgb(255 255 255 / 0.85);
  }

  /* Dimension lines, as on a proof sheet: the front of the print, in centimetres. */
  .cfg-measure {
    position: absolute;
    color: var(--proof-ink);
    font: 450 11px/1 var(--font-mono);
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
  }
  .cfg-measure::before { content: ""; position: absolute; border: 0 solid var(--proof-line); }
  .cfg-measure--w {
    top: calc(100% + 12px);
    left: calc(var(--fx0) * 100%);
    right: calc((1 - var(--fx1)) * 100%);
    height: 9px;
    border-inline: 1px solid var(--proof-line);
  }
  .cfg-measure--w::before { left: 0; right: 0; top: 4px; border-top-width: 1px; }
  .cfg-measure--h {
    left: calc(100% + 12px);
    top: calc(var(--fy0) * 100%);
    bottom: calc((1 - var(--fy1)) * 100%);
    width: 9px;
    border-block: 1px solid var(--proof-line);
  }
  .cfg-measure--h::before { top: 0; bottom: 0; left: 4px; border-left-width: 1px; }
  .cfg-measure__text {
    position: absolute;
    top: 50%;
    left: 50%;
    translate: -50% -50%;
    padding: 2px 6px;
    background: var(--proof);
    white-space: nowrap;
  }
  .cfg-measure--h .cfg-measure__text { writing-mode: vertical-rl; padding: 6px 2px; }

  /* ------------------------------------------------------------------ captions */
  .cfg-caption {
    display: grid;
    gap: var(--space-2);
    padding-block-start: var(--space-4);
    max-inline-size: 60ch;
  }
  .cfg-caption__lead { font-size: var(--step--1); line-height: 1.5; color: var(--ink); text-wrap: pretty; }
  .cfg-caption__line { font-size: var(--step--1); line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
  .cfg-caption__note { display: grid; justify-items: start; gap: 0; }
  .cfg-caption__action { min-block-size: 36px; padding-inline: 0; font-size: var(--step--1); }

  .cfg-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-5);
    margin-block-start: var(--space-1);
    font: 450 var(--step--2)/1.4 var(--font-mono);
    letter-spacing: 0.04em;
    color: var(--ink-2);
  }
  .cfg-legend__item { display: inline-flex; align-items: center; gap: var(--space-2); }
  .cfg-key { flex: none; inline-size: 18px; block-size: 12px; }
  .cfg-key--trim { background: light-dark(#b9b9b9, #5c5c5c); box-shadow: inset 0 0 0 1px var(--proof-line); }
  .cfg-key--wrap {
    background:
      repeating-linear-gradient(135deg, rgb(255 255 255 / 0.7) 0 1.25px, rgb(0 0 0 / 0.35) 1.25px 2.25px, transparent 2.25px 6px),
      light-dark(#9a9a9a, #6a6a6a);
  }
  .cfg-key--edge { border: 1px dashed currentColor; }

  /* ------------------------------------------------------------------ On a wall */
  .cfg-stage--wall { background: #ecebe8; }
  .cfg-wall {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    max-inline-size: none;
  }
  .cfg-tones__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin-block-start: var(--space-1); }
  .cfg-tones__label {
    font: 600 var(--step--2)/1 var(--font-ui);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-2);
  }
  .cfg-tones > label { min-block-size: 36px; padding-inline: var(--space-3); }
  .cfg-tones__swatch {
    flex: none;
    inline-size: 12px;
    block-size: 12px;
    background: var(--swatch);
    box-shadow: 0 0 0 1px light-dark(rgb(0 0 0 / 0.35), rgb(255 255 255 / 0.35));
  }

  /* ------------------------------------------------------------------ Edge: the CSS 3D box */
  .cfg-stage--edge {
    display: grid;
    place-items: center;
    perspective: 1400px;
    perspective-origin: 50% 50%;
    touch-action: pan-y; /* a horizontal drag turns the box; vertical swipes still scroll */
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
  }
  .cfg-stage--edge:has(.cfg-box[data-dragging]) { cursor: grabbing; }
  .cfg-box[data-dragging] { transition: none; }
  .cfg-box {
    /* --wcm/--hcm/--dcm: the object's size in cm; --s: px per cm so the turned box fits the stage. */
    --s: min(calc(58cqi / (var(--wcm, 30) + var(--dcm, 4))), calc(72cqb / var(--hcm, 40)));
    --bw: calc(var(--wcm, 30) * var(--s));
    --bh: calc(var(--hcm, 40) * var(--s));
    --bd: calc(var(--dcm, 4) * var(--s));
    position: relative;
    inline-size: var(--bw);
    block-size: var(--bh);
    transform-style: preserve-3d;
    /* A hung print is a little below the eye: a slight tilt shows its top edge as it turns. */
    transform: rotateX(var(--tilt, -6deg)) rotateY(var(--turn, -35deg));
    transition: transform var(--dur-pour) var(--ease-pour);
  }
  .cfg-box[data-turn="0"] { --tilt: 0deg; }
  .cfg-box__face {
    position: absolute;
    left: 50%;
    top: 50%;
    overflow: hidden;
    backface-visibility: hidden;
    background: #d9d4cb;
  }
  .cfg-box__skin { position: absolute; inset: 0; background-repeat: no-repeat; }
  .cfg-box__skin[data-mirror="x"] { transform: scaleX(-1); }
  .cfg-box__skin[data-mirror="y"] { transform: scaleY(-1); }
  .cfg-box__face--front, .cfg-box__face--back { inline-size: var(--bw); block-size: var(--bh); }
  .cfg-box__face--front { transform: translate(-50%, -50%) translateZ(calc(var(--bd) / 2)); }
  .cfg-box__face--back { transform: translate(-50%, -50%) rotateY(180deg) translateZ(calc(var(--bd) / 2)); background: #cfc8bc; }
  .cfg-box__face--back .cfg-box__skin { display: none; }
  .cfg-box__face--left, .cfg-box__face--right { inline-size: var(--bd); block-size: var(--bh); }
  .cfg-box__face--left { transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--bw) / 2)); }
  .cfg-box__face--right { transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--bw) / 2)); }
  .cfg-box__face--top, .cfg-box__face--bottom { inline-size: var(--bw); block-size: var(--bd); }
  .cfg-box__face--top { transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--bh) / 2)); }
  .cfg-box__face--bottom { transform: translate(-50%, -50%) rotateX(-90deg) translateZ(calc(var(--bh) / 2)); }
  /* Sides read as sides: a little shade (the edges are what a room lights, never the picture). */
  .cfg-box__face:is(.cfg-box__face--left, .cfg-box__face--right, .cfg-box__face--top, .cfg-box__face--bottom)::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / var(--shade, 0.16));
    pointer-events: none;
  }
  .cfg-box__face--top { --shade: 0.06; }
  .cfg-box__face--bottom { --shade: 0.26; }
  .cfg-box__gap { display: none; }

  .cfg-box[data-edge="black"] .cfg-box__face:not(.cfg-box__face--front) { background: #121110; }
  .cfg-box[data-edge="white"] .cfg-box__face:not(.cfg-box__face--front) { background: #f4f2ee; }
  .cfg-box:is([data-edge="black"], [data-edge="white"], [data-edge="framed"]) .cfg-box__face:not(.cfg-box__face--front) .cfg-box__skin { display: none; }

  /* Framed canvas: the moulding, the black canvas edge in the gap, then the canvas. */
  .cfg-box[data-edge="framed"] .cfg-box__face { background: var(--frame, #1c1a18); }
  .cfg-box[data-edge="framed"] .cfg-box__gap {
    display: block;
    position: absolute;
    inset: var(--in1y) var(--in1x);
    background: #0d0c0b;
    box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.5);
  }
  .cfg-box[data-edge="framed"] .cfg-box__face--front > .cfg-box__skin { inset: var(--in2y) var(--in2x); }
  .cfg-box[data-edge="framed"] .cfg-box__face--front::before {
    content: "";
    position: absolute;
    inset: 0;
    box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.22);
    pointer-events: none;
  }
  .cfg-box[data-frame="natural"] .cfg-box__face,
  .cfg-box[data-frame="walnut"] .cfg-box__face {
    background-image: repeating-linear-gradient(92deg, rgb(255 255 255 / 0.07) 0 2px, transparent 2px 5px, rgb(0 0 0 / 0.06) 5px 6px, transparent 6px 11px);
  }

  /* Phase 3 (vision §F3): the WebGL model draws inside the host. On its first frame the canvas fades
     in over 180 ms (gl.css) while the box fades out; the box stays underneath as the fallback and
     comes straight back if the model goes (released, replaced, context lost). Calm: no fade. */
  .cfg-stage--edge[data-gl-state="live"] > .cfg-box {
    opacity: 0;
    visibility: hidden;
    transition: opacity 180ms cubic-bezier(0.2, 0, 0, 1), visibility 0s linear 180ms;
  }
  html[data-motion="calm"] .cfg-stage--edge[data-gl-state="live"] > .cfg-box { transition: none; }
  .cfg-turn__gl[data-busy] { cursor: progress; opacity: 0.72; }

  .cfg-turn {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2);
    max-inline-size: 30rem;
  }
  .cfg-turn .button {
    min-block-size: 44px;
    padding: 6px var(--space-2);
    font-size: var(--step--1);
    gap: 0.4em;
    white-space: nowrap;
  }
  .cfg-turn .button > svg { inline-size: 1.15em; block-size: 1.15em; }
  .cfg-turn__button[aria-pressed="true"] { --_bd: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
  .cfg-turn__gl { justify-self: start; min-block-size: 44px; }
  .cfg-turn__desc { min-block-size: 3em; }

  /* ------------------------------------------------------------------ options */
  .cfg-options { display: grid; gap: var(--space-6); }
  .cfg-field { gap: var(--space-2); }
  .cfg-field > legend {
    margin-block-end: var(--space-3);
    font: 600 var(--step--2)/1.3 var(--font-ui);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-2);
  }
  .cfg-field__notes { grid-column: 1 / -1; display: grid; gap: var(--space-1); margin-block-start: var(--space-1); }
  .cfg-field__notes:not(:has(> :not([hidden], :empty))) { display: none; }
  .cfg-field__note {
    font-size: var(--step--1);
    line-height: 1.45;
    color: var(--ink-2);
    text-wrap: pretty;
  }
  .cfg-field__note:empty { display: none; }
  .cfg-field__note--soft { color: var(--ink); }

  /* Column counts per group (the options column is 300–560 px wide). */
  .cfg-field--productType,
  .cfg-field--paper { grid-template-columns: minmax(0, 1fr); }
  .cfg-field--framedType,
  .cfg-field--size,
  .cfg-field--canvasEdge,
  .cfg-field--frame { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  @container cfg-options (min-width: 300px) {
    .cfg-field--productType { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  @container cfg-options (min-width: 520px) {
    .cfg-field--paper { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  @container cfg-options (min-width: 640px) {
    .cfg-field--size,
    .cfg-field--canvasEdge,
    .cfg-field--frame { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  }

  .cfg-choice { min-block-size: 64px; align-content: start; }
  .cfg-choice .choice__sub { margin-block-start: 1px; }
  .cfg-choice .choice__note { margin-block-start: 2px; }
  .cfg-choice .choice__note:empty { display: none; }
  .cfg-field--size .choice__sub > span { white-space: nowrap; }
  @container cfg-options (max-width: 419.98px) {
    /* Narrow cards: dimensions, then the price on its own line. */
    .cfg-field--size .choice__sub { display: grid; }
    .cfg-field--size .cfg-sep { display: none; }
  }
  .cfg-field--size .choice__note,
  .cfg-field--framedType .choice__note { font-size: var(--step--2); line-height: 1.4; }
  /* "Soft up close": a quiet mono tag; "Not available…": the reason, in words. */
  .cfg-field--size .choice:not(:has(:disabled)) .choice__note {
    font-family: var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-2);
  }

  /* Cards with a picture: picture beside the words, or above them where the card is narrow. */
  .cfg-choice--visual {
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: var(--space-3);
    align-items: center;
    align-content: center;
  }
  .cfg-choice--visual > .cfg-choice__visual { grid-row: 1 / span 3; align-self: center; }
  .cfg-choice--visual > :not(.cfg-choice__visual, input) { grid-column: 2; }
  .cfg-choice__visual { display: block; color: var(--ink-2); line-height: 0; }
  /* reset.css caps svg at 100% wide, which lets a shrink-to-fit card squeeze the picture to 0. */
  .cfg-choice__visual > svg { max-inline-size: none; }
  .cfg-choice:has(:checked) .cfg-choice__visual { color: var(--ink); }

  /* Picture above the words (three or four cards to a row). */
  @container cfg-options (min-width: 300px) {
    .cfg-field--productType .cfg-choice--visual {
      grid-template-columns: minmax(0, 1fr);
      align-content: start;
      padding-inline: var(--space-3);
    }
    .cfg-field--productType .cfg-choice--visual > * { grid-column: 1; }
    .cfg-field--productType .cfg-choice__visual { grid-row: auto; justify-self: start; margin-block-end: var(--space-2); }
  }
  @container cfg-options (min-width: 520px) {
    .cfg-field--paper .cfg-choice--visual { grid-template-columns: minmax(0, 1fr); align-content: start; }
    .cfg-field--paper .cfg-choice--visual > * { grid-column: 1; }
    .cfg-field--paper .cfg-choice__visual { grid-row: auto; justify-self: start; margin-block-end: var(--space-2); }
  }
  :is(.cfg-field--canvasEdge, .cfg-field--frame) .cfg-choice--visual {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
  }
  :is(.cfg-field--canvasEdge, .cfg-field--frame) .cfg-choice--visual > * { grid-column: 1; }
  :is(.cfg-field--canvasEdge, .cfg-field--frame) .cfg-choice__visual { grid-row: auto; justify-self: start; margin-block-end: var(--space-2); }

  .cfg-icon { inline-size: 36px; block-size: 36px; }
  .cfg-diagram { inline-size: 56px; block-size: 45px; }

  /* Paper: a sheet with a turned corner. Frames: the print itself, small, in each moulding. */
  .cfg-paper { inline-size: 28px; block-size: 36px; color: var(--ink-2); }
  .cfg-frame {
    --print-ar: 0.75;
    display: block;
    block-size: 44px;
    inline-size: calc((44px - 10px) * var(--print-ar) + 10px);
    padding: 5px;
    background: var(--frame-fill, #1c1a18);
    box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.3), 0 0 0 1px light-dark(transparent, rgb(255 255 255 / 0.14));
  }
  .cfg-frame[data-landscape] {
    inline-size: 56px;
    block-size: calc((56px - 10px) / var(--print-ar) + 10px);
  }
  .cfg-frame__art {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    background-color: #8a8076;
    background-repeat: no-repeat;
    box-shadow: 0 0 0 1px rgb(0 0 0 / 0.35);
  }
  .cfg-frame[data-frame="black"] { --frame-fill: #1c1a18; }
  .cfg-frame[data-frame="white"] { --frame-fill: #f3f1ec; box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.22), 0 0 0 1px light-dark(rgb(0 0 0 / 0.12), transparent); }
  .cfg-frame[data-frame="natural"] {
    background: repeating-linear-gradient(94deg, #c9a679 0 2px, #b8915f 2px 3px, #d0ae83 3px 6px, #bf9967 6px 7px);
  }
  .cfg-frame[data-frame="walnut"] {
    background: repeating-linear-gradient(94deg, #5c3f2c 0 2px, #4a3122 2px 3px, #654632 3px 6px, #513727 6px 7px);
  }

  /* ------------------------------------------------------------------ price and buying */
  .cfg-buy {
    gap: var(--space-4);
    padding-block-start: var(--space-5);
    border-block-start: 1px solid var(--rule);
  }
  .cfg-buy__main { display: grid; gap: var(--space-4); }
  .cfg-buy__head { display: grid; gap: var(--space-1); min-inline-size: 0; }
  .cfg-add { inline-size: 100%; min-block-size: 52px; }
  .cfg-add > svg { inline-size: 1.25em; block-size: 1.25em; }
  .cfg-buy__lines { display: grid; gap: var(--space-2); }
  .cfg-buy__lines .price__line + .price__line { margin-block-start: 0; }
  .cfg-link {
    display: inline-block;
    min-block-size: 24px;
    padding-block: 2px;
    font-weight: 600;
    color: var(--ink);
  }
  .cfg-buy__more { margin: 0; }
  .cfg-part { white-space: nowrap; }

  /* In a sheet or dialog the total and the button live in the dialog's footer (always in view). */
  .cfg-foot.dialog__foot {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-content: stretch;
    gap: var(--space-3);
    padding-block: var(--space-3) calc(var(--space-3) + env(safe-area-inset-bottom));
  }
  .cfg-foot .cfg-buy__main { gap: var(--space-3); }
  .cfg-foot .cfg-buy__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--space-4);
    row-gap: 2px;
  }
  .cfg-foot .price__summary { flex: 1 1 12rem; font-size: var(--step--2); text-wrap: pretty; }
  .cfg-foot .cfg-add { min-block-size: 48px; }
  .cfg-foot .cfg-part--price { display: none; } /* the total is right there */
  /* A wide dialog: the total on the left, the button on the right. */
  .dialog--modal .cfg-foot .cfg-buy__main {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-5);
  }
  .dialog--modal .cfg-foot .cfg-buy__head { display: grid; gap: 2px; }
  .dialog--modal .cfg-foot .cfg-add { inline-size: auto; padding-inline: var(--space-6); }

  .cfg-status {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--step--1);
    line-height: 1.5;
    color: var(--ink);
  }
  .cfg-status__icon {
    flex: none;
    inline-size: 16px;
    block-size: 16px;
    margin-block-start: 0.2em;
    background: var(--ok);
    mask: var(--icon-check) center / contain no-repeat;
  }
  .cfg-status:is([data-tone="alert"], [data-tone="blocked"]) { color: var(--alert); }
  .cfg-status:is([data-tone="alert"], [data-tone="blocked"]) .cfg-status__icon { background: var(--alert); mask-image: var(--icon-alert); }
  .cfg-status a { font-weight: 600; white-space: nowrap; color: var(--ink); }
  .cfg-status { transition: opacity var(--dur-settle) var(--ease-pour), translate var(--dur-settle) var(--ease-pour); }
  @starting-style {
    .cfg-status { opacity: 0; translate: 0 4px; }
  }

  .cfg-notes {
    display: grid;
    gap: var(--space-2);
    font-size: var(--step--1);
    line-height: 1.5;
    color: var(--ink-2);
  }
  .cfg-notes > li { position: relative; padding-inline-start: var(--space-4); text-wrap: pretty; }
  .cfg-notes > li::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0.74em;
    inline-size: 7px;
    block-size: 1px;
    background: var(--edge);
  }

  /* ------------------------------------------------------------------ the line under a dialog title */
  .cfg-for {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-2);
    margin-block: calc(-1 * var(--space-2)) var(--space-5);
    color: var(--ink-2);
  }
  .cfg-for__title { font-size: var(--step-1); line-height: 1.3; color: var(--ink); }
  .cfg-for__id { font: 450 var(--step--2)/1 var(--font-mono); letter-spacing: 0.08em; }
  .cfg-for__sep { color: var(--ink-3); }
  .cfg-for .ai-stamp { align-self: center; }

  /* ------------------------------------------------------------------ below 1024: teaser and buy bar */
  .cfg-teaser { display: grid; justify-items: start; gap: var(--space-4); }
  .cfg-teaser__line { font-size: var(--step-1); line-height: 1.45; max-inline-size: 34ch; text-wrap: pretty; }
  .cfg-teaser__sizes {
    margin-block-start: calc(-1 * var(--space-2));
    font: 450 var(--step--2)/1.6 var(--font-mono);
    letter-spacing: 0.04em;
    color: var(--ink-2);
  }
  .cfg-teaser__sizes > span { white-space: nowrap; }
  .cfg-teaser__current { margin-block-start: calc(-1 * var(--space-1)); }
  .cfg-teaser__open { min-inline-size: min(100%, 15rem); }

  .cfg-buybar__intro { font-size: var(--step-0); }
  .cfg-buybar__edit {
    display: grid;
    justify-items: start;
    gap: 2px;
    min-inline-size: 0;
    min-block-size: 44px;
    padding: 2px 4px 2px 0;
    border: 0;
    background: none;
    font: inherit;
    text-align: start;
    color: var(--ink-2);
    cursor: pointer;
  }
  .cfg-buybar__summary { max-inline-size: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cfg-buybar__hint {
    font: 600 var(--step--2)/1.2 var(--font-ui);
    letter-spacing: 0.02em;
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-underline-offset: 0.3em;
  }
  .cfg-buybar__edit:hover .cfg-buybar__hint { text-decoration-thickness: 2px; }
  .cfg-buybar__add[data-added] { gap: 0.45em; }
  .cfg-check {
    display: inline-block;
    inline-size: 1.1em;
    block-size: 1.1em;
    background: currentColor;
    mask: var(--icon-check) center / contain no-repeat;
  }
  @media (max-width: 1023.98px) {
    /* The bar's measured height (index.js) is the room kept below the page's last line. */
    body:has(.cfg-buybar:not([hidden])) { padding-block-end: var(--buybar-h, 72px); }
  }

  /* ------------------------------------------------------------------ dialogs */
  .cfg-dialog.dialog--modal {
    inline-size: min(1120px, 100% - 2 * var(--margin));
    max-block-size: min(92svh, 100% - 2 * var(--space-5));
  }
  .cfg-dialog .dialog__body,
  .cfg-sheet .dialog__body { padding-block-end: var(--space-6); }
  .cfg-original.dialog--modal { inline-size: min(980px, 100% - 2 * var(--margin)); }
  .cfg-original__figure { display: grid; gap: var(--space-3); margin: 0; }
  .cfg-original__figure img {
    inline-size: auto;
    max-inline-size: 100%;
    max-block-size: 68svh;
    margin-inline: auto;
    background: var(--proof);
  }

  .cfg-error { display: grid; justify-items: start; gap: var(--space-3); }

  /* ------------------------------------------------------------------ display modes */
  @media (forced-colors: active) {
    /* The previews are pictures of the product: keep their colours, frame them in system ink.
       The format pictograms are line drawings: they take the system's text colour. */
    .cfg-stage, .cfg-key, .cfg-tones__swatch, .cfg-frame, .cfg-paper, .cfg-diagram { forced-color-adjust: none; }
    .cfg-choice__visual, .cfg-paper, .cfg-diagram { color: CanvasText; }
    .cfg-stage { outline: 1px solid CanvasText; }
    .cfg-measure__text { color: #fff; background: #000; }
    .cfg-status__icon, .cfg-check { forced-color-adjust: none; background: CanvasText; }
    .cfg-turn__button[aria-pressed="true"] { box-shadow: inset 0 0 0 1px Highlight; border-color: Highlight; }
  }
  @media (prefers-contrast: more) {
    .cfg-panel { --proof-ink: light-dark(#111, #f2f2f2); --proof-line: light-dark(rgb(0 0 0 / 0.8), rgb(255 255 255 / 0.85)); }
  }
}
