/* Syno product configurator.
   Consumes the colour and face tokens from synoint-base.css. The only values
   defined here are the ones that govern this form's rhythm.

   Spacing is a 4px scale with named jobs, not per-element guesses. The ratio
   that matters is intra-field vs inter-field: a label, its help line and its
   control must read as ONE object, with clear air before the next one. When
   those two distances are similar the form reads as an undifferentiated list,
   which is the single most common failure in long forms.

   Type: the display face (Bricolage) carries headings, field labels and
   numbers - anything the eye should land on. The body face (Hanken) carries
   help text, inputs and option labels - anything that should recede. Sizes are
   a scale of five steps; nothing in the form is sized ad hoc. */

/* The column width lives on <body> because the breadcrumb and title sit OUTSIDE
   .cfg and must read the same value - custom properties inherit down, not up. */
body.cfg-open {
  --cfg-w: 880px;
}

/* `hidden` must actually hide.
   The attribute works through the browser's own `[hidden]{display:none}`, which
   ANY author `display` declaration outranks - and `.btn` in synoint-base.css
   sets `display:inline-flex`. The result was Continue, Back and Add to cart all
   visible on every step, however faithfully the JS set `.hidden = true`.
   This re-asserts the browser's intent; `!important` is the point, not a patch. */
.cfg [hidden] {
  display: none !important;
}

.cfg {
  /* spacing */
  --cfg-tight: 4px;   /* label -> help */
  --cfg-snug: 10px;   /* help -> control */
  --cfg-field: 30px;  /* field -> field */
  --cfg-block: 34px;  /* heading -> first field */

  /* Ratio of the font's glyph box to its size, measured on Bricolage Grotesque
     at 16px: 19.2 / 16 = 1.2. Used to centre controls on text. */
  --cfg-glyph: 1.2;

  /* type scale */
  --cfg-t-heading: clamp(24px, 2.6vw, 31px);
  --cfg-t-label: 16px;
  --cfg-t-body: 15px;
  --cfg-t-help: 14px;
  --cfg-t-meta: 12px;

  margin-top: 28px;
}

/* ---------- progress ---------- */

.cfg-progress {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}

.cfg-progress-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 8px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-3);
  font-size: 13px;
  font-weight: 500;
  transition: 0.2s var(--ease);
}

.cfg-progress-item.is-done {
  color: var(--text-2);
  border-color: rgba(75, 123, 255, 0.35);
  cursor: pointer;
}

.cfg-progress-item.is-done:hover {
  background: rgba(75, 123, 255, 0.1);
  color: var(--ink);
}

.cfg-progress-item.is-current {
  color: var(--ink);
  border-color: var(--brand);
  background: rgba(75, 123, 255, 0.14);
}

.cfg-progress-num {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  flex: none;
}

.cfg-progress-item.is-current .cfg-progress-num {
  background: var(--brand);
  color: #fff;
}

.cfg-progress-item.is-done .cfg-progress-num::after {
  content: '✓';
}

.cfg-progress-item.is-done .cfg-progress-num {
  color: transparent;
  background: rgba(75, 123, 255, 0.3);
  position: relative;
}

.cfg-progress-item.is-done .cfg-progress-num::after {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--ink);
}

/* Reads as a caption, not a sentence: mono-ish tracking and uppercase keep it
   as a wayfinding label rather than something to read. */
.cfg-progress-count {
  margin: 0 0 34px;
  color: var(--text-3);
  font-size: var(--cfg-t-meta);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

/* ---------- steps ---------- */

.cfg-step {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

/* Visually hidden, deliberately not removed.
   On screen it repeats the step indicator directly above it, so it is noise.
   In the markup it is the <fieldset>'s <legend>, which is what gives the group
   an accessible name, and it is where focus lands when a step opens - delete it
   and screen-reader users lose both. */
.cfg-step-title {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ...but a keyboard user must still see where focus went. */
.cfg-step-title:focus-visible {
  position: static;
  width: auto;
  height: auto;
  margin: 0 0 var(--cfg-tight);
  clip-path: none;
  font-family: var(--font-display);
  font-size: var(--cfg-t-heading);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--ink);
  outline: 2px solid var(--brand);
  outline-offset: 4px;
  border-radius: 4px;
}

.cfg-step-desc {
  color: var(--text-2);
  font-size: var(--cfg-t-body);
  line-height: 1.55;
  margin: 8px 0 0;
  max-width: 60ch;
}

.cfg-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--cfg-field) 16px;

  /* No margin: the step heading above is visually hidden, so the gap below the
     step counter is the only one needed. */
  margin-top: 0;
}

.cfg-field {
  grid-column: 1 / -1;
  min-width: 0;
}

.cfg-field--half {
  grid-column: span 1;
}

/* ---------- labels and inputs ---------- */

.cfg-label {
  display: block;
  font-family: var(--font-display);
  font-size: var(--cfg-t-label);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.3;
  color: var(--ink);

  /* Default: the label sits directly above its control, so it needs the
     control gap. */
  margin: 0 0 var(--cfg-snug);
}

/* When a help line follows, label and help are one unit - close them right up
   and let the help line own the gap to the control. `:last-of-type` cannot do
   this: the label is the only <label> in the field either way. */
.cfg-label:has(+ .cfg-help) {
  margin-bottom: var(--cfg-tight);
}

.cfg-sublabel {
  display: block;
  font-size: var(--cfg-t-meta);
  font-weight: 500;
  color: var(--text-3);
  margin: 0 0 6px;
}

.cfg-req {
  color: var(--brand);
  margin-left: 3px;
  font-weight: 400;
}

/* Runs the full width of the control it describes. A measure-capped help line
   sitting above a full-width select reads as a stray fragment - the shared
   right edge is worth more here than the ideal line length, because these are
   one or two lines, not paragraphs. */
.cfg-help {
  margin: 0 0 var(--cfg-snug);
  color: var(--text-2);
  font-size: var(--cfg-t-help);
  line-height: 1.5;
}

.cfg-input {
  width: 100%;
  padding: 12px 15px;
  background: var(--frame);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-btn);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--cfg-t-body);
  line-height: 1.45;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.cfg-input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-glow);
}

.has-error .cfg-input {
  border-color: #ff5f6d;
}

.cfg-error {
  margin: 6px 0 0;
  color: #ff8a92;
  font-size: 13px;
}

/* ---------- radios ---------- */

.cfg-radios {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cfg-radio {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 18px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-2);
  cursor: pointer;
  transition: 0.2s var(--ease);
}

/* A pill is an option, not an object. It takes the body face at body size -
   the display face at 16px/700 (inherited from .cfg-card-label) made these
   shout as loudly as the question above them. */
.cfg-radio .cfg-card-label {
  font-family: var(--font-body);
  font-size: var(--cfg-t-body);
  font-weight: 500;
  letter-spacing: 0;
}

.cfg-radio:hover {
  border-color: rgba(75, 123, 255, 0.45);
  color: var(--ink);
}

.cfg-radio:has(input:checked) {
  border-color: var(--brand);
  background: rgba(75, 123, 255, 0.14);
  color: var(--ink);
}

.cfg-radio input,
.cfg-card input,
.cfg-check input {
  accent-color: var(--brand);
  flex: none;
}

/* ---------- price cards ---------- */

.cfg-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

@media (min-width: 700px) {
  .cfg-cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Two columns: the control, then everything it labels. The radio sits on the
   same baseline as "125 respondents" instead of floating on a line of its own,
   and the note and price align under the count rather than under the dot. */
.cfg-card {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  column-gap: 11px;
  row-gap: 14px;
  align-items: start;
  padding: 18px;
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  box-shadow: inset 0 1px 0 var(--inset-top);
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: 0.2s var(--ease);
}

/* Optical alignment, expressed as arithmetic rather than a nudge.
   The control must centre on the TEXT, not on the line box. Measured on the
   real render: a 16px label has a 20px line box but a 19.2px glyph box (1.2em,
   the font's own content height), and that glyph box sits at the TOP of the
   line box rather than centred in it. Centring on the line box therefore
   leaves the control 0.4px low - visible as a slight sag next to bold text.

       control centre = (glyph box - control) / 2
                      = (1.2em - 16px) / 2

   `font-size` is set on the input purely so `em` resolves against the label's
   size, which keeps this correct if the type scale ever changes.
   `align-items: start` stays deliberate: centring the row would drift the
   control downwards the moment a label wraps to two lines. */
.cfg-card .cfg-card-label,
.cfg-check .cfg-card-label {
  font-size: var(--cfg-t-label);
  line-height: 20px;
}

.cfg-card > input,
.cfg-check > input {
  width: 16px;
  height: 16px;
  font-size: var(--cfg-t-label);
  margin: calc((var(--cfg-glyph, 1.2) * 1em - 16px) / 2) 0 0;
  flex: none;
}

.cfg-card > input {
  grid-area: 1 / 1;
}

.cfg-card .cfg-card-body {
  grid-area: 1 / 2;
}

/* Row 2, second column - so prices line up across cards of unequal text. */
.cfg-card .cfg-card-price {
  grid-area: 2 / 2;
  align-self: end;
}

.cfg-card:hover {
  border-color: rgba(75, 123, 255, 0.45);
  transform: translateY(-2px);
}

.cfg-card:has(input:checked) {
  border-color: var(--brand);
  box-shadow: inset 0 1px 0 var(--inset-top), 0 18px 44px -26px var(--brand-glow);
}

.cfg-card-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.cfg-card-label {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.cfg-card-note {
  color: var(--text-2);
  font-size: 13px;
  line-height: 1.45;
}

.cfg-card-price {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.cfg-card-price:empty::before {
  content: 'Select a market';
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 400;
  color: var(--text-3);
}

.cfg-card-badge {
  position: absolute;
  top: -9px;
  right: 14px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ---------- checkboxes ---------- */

.cfg-checks {
  display: grid;
  gap: 10px;
}

.cfg-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 16px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: 0.2s var(--ease);
}

.cfg-check:hover {
  border-color: rgba(75, 123, 255, 0.45);
}

.cfg-check:has(input:checked) {
  border-color: var(--brand);
  background: rgba(75, 123, 255, 0.1);
}

/* Sizing and offset are set once, with the cards, in the alignment block above. */

/* ---------- file upload ----------
   The browser's own control, restyled. Its button is a shadow part, so it is
   targeted through ::file-selector-button rather than replaced with a fake one
   that would lose keyboard support and drag-and-drop. */

.cfg-file {
  padding: 9px 12px;
  cursor: pointer;
}

.cfg-file::file-selector-button {
  margin-right: 14px;
  padding: 8px 16px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: 0.2s var(--ease);
}

.cfg-file::file-selector-button:hover {
  background: rgba(75, 123, 255, 0.16);
  border-color: var(--brand);
}

.cfg-file-limit {
  margin: 7px 0 0;
  color: var(--text-3);
  font-size: var(--cfg-t-meta);
  line-height: 1.5;
}

/* ---------- price points ---------- */

.cfg-price-points {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

@media (min-width: 700px) {
  .cfg-price-points {
    grid-template-columns: repeat(5, 1fr);
  }
}

/* ---------- notice & summary ---------- */

/* This is a statement of fact, not a question. It previously carried a tinted
   panel, a full border and a display-face heading - the same weight as the
   inputs around it - so the eye stopped on something it can do nothing about.
   Demoted to a hairline rule and body text: still findable, no longer
   competing with the fields. */
.cfg-notice {
  padding: 2px 0 2px 16px;
  border-left: 2px solid color-mix(in srgb, var(--brand) 55%, transparent);
}

.cfg-notice strong {
  display: block;
  font-family: var(--font-body);
  font-size: var(--cfg-t-help);
  font-weight: 600;
  color: var(--text-2);
}

.cfg-notice p {
  margin: 2px 0 0;
  color: var(--text-3);
  font-size: var(--cfg-t-help);
  line-height: 1.5;
}

.cfg-summary h3 {
  font-family: var(--font-display);
  font-size: 17px;
  margin: 0 0 10px;
}

.cfg-summary dl {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 8px 20px;
  margin: 0;
  padding: 16px 18px;
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
}

.cfg-summary dt {
  color: var(--text-3);
  font-size: 14px;
}

.cfg-summary dd {
  margin: 0;
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  overflow-wrap: anywhere;
}

/* ---------- focused mode ----------
   Once the flow is open the configuration IS the page. The gallery, the tabs
   and the related products are browsing aids - they are noise next to a form
   someone is part-way through, and they cost the form half its width.

   Note the selector: WooCommerce puts `.woocommerce` on <body> itself, so
   `body.cfg-open .woocommerce` would look for a DESCENDANT carrying that class
   and match nothing. Both classes sit on the same element, hence no space.
   That also gives these rules more specificity than `.woocommerce div.product`
   in theme.css, so the two-column grid is overridden without !important. */

body.cfg-open.woocommerce div.product {
  grid-template-columns: minmax(0, 1fr);
}

body.cfg-open.woocommerce div.product div.images,
body.cfg-open.woocommerce div.product .woocommerce-tabs,
body.cfg-open.woocommerce div.product .related,
body.cfg-open.woocommerce div.product .upsells,
body.cfg-open.woocommerce div.product .product_meta,
body.cfg-open.woocommerce .woocommerce-product-details__short-description {
  display: none;
}

/* A form the full width of a 1280px page is unreadable, so the content column
   narrows to --cfg-w. Crucially the BREADCRUMB AND TITLE narrow with it: when
   only the form was inset, its left edge sat ~220px inside the title above it
   and the page read as two unrelated documents. One column, one left edge. */
body.cfg-open .shop-main > .wrap {
  max-width: var(--cfg-w, 880px);
}

/* The product title is hidden once the flow is open - it was answered on the
   overview screen and repeating it above every step is chrome. It is hidden
   VISUALLY rather than removed, because it is the page's <h1>: with
   `display:none` the document would have no heading at all for a screen reader
   while the form is open. The breadcrumb still names the product for anyone
   who needs it. */
body.cfg-open.woocommerce div.product .product_title {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- intro ---------- */

.cfg-intro-price {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 20px;
}

.cfg-intro-from {
  color: var(--text-3);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
}

.cfg-intro-amount,
.cfg-intro-amount .woocommerce-Price-amount {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
}

/* What the buyer gets, on the overview rather than buried mid-flow. Ticks, not
   bullets: these are inclusions, and a tick says so without a word of copy. */
.cfg-intro-points {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  display: grid;
  gap: 9px;
}

.cfg-intro-points li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--text-2);
  font-size: var(--cfg-t-body);
  line-height: 1.5;
}

.cfg-intro-points svg {
  width: 17px;
  height: 17px;
  flex: none;
  color: var(--brand);
  /* Same arithmetic as the option controls: centre the tick on the text's
     glyph box, not on its line box. */
  margin-top: calc((var(--cfg-glyph, 1.2) * 1em - 17px) / 2);
}

.cfg-intro-button {
  font-size: 16px;
  padding: 14px 26px;
}

.cfg-intro-button svg {
  width: 18px;
  height: 18px;
  transition: transform 0.2s var(--ease);
}

.cfg-intro-button:hover svg {
  transform: translateX(3px);
}

.cfg-intro-note {
  margin: 10px 0 0;
  color: var(--text-3);
  font-size: 13px;
}

/* ---------- running price + actions ---------- */

.cfg-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 26px;
  padding: 16px 18px;
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  box-shadow: inset 0 1px 0 var(--inset-top);
  border-radius: var(--radius-card);
}

.cfg-bar-price {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.cfg-bar-caption {
  color: var(--text-3);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
}

.cfg-bar-amount {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--ink);
}

.cfg-bar-amount .woocommerce-Price-amount {
  color: inherit;
  font: inherit;
}

.cfg-bar-note {
  color: var(--text-3);
  font-size: 12.5px;
}

.cfg-bar-actions {
  display: flex;
  gap: 10px;
  margin-left: auto;
}

.cfg-bar-actions .btn {
  cursor: pointer;
  white-space: nowrap;
}

/* On a phone three buttons in a row wrap their labels and grow to 86px tall.
   Stack them instead, primary first so the forward action is under the thumb
   and the destructive-feeling one is not. */
@media (max-width: 640px) {
  .cfg-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }

  .cfg-bar-actions {
    margin-left: 0;
    display: grid;
    grid-template-columns: 1fr;
  }

  .cfg-bar-actions .btn {
    width: 100%;
    padding-block: 14px;
  }

  [data-cfg-next],
  [data-cfg-submit] {
    order: -1;
  }
}

.cfg-from {
  color: var(--text-3);
  font-size: 0.7em;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
}

/* ---------- no-JS ---------- */
/* Without JS every step is shown and the server validates. Hide the stepper
   chrome so nothing promises behaviour that is not there. */

.no-js .cfg-progress,
.no-js .cfg-progress-count,
.no-js .cfg-bar-actions [data-cfg-next],
.no-js .cfg-bar-actions [data-cfg-prev] {
  display: none;
}

.no-js .cfg-step {
  margin-bottom: 34px;
}
