/* Hallmark · pre-emit critique: P5 H5 E4 S5 R5 V4 */
/* Hallmark · macrostructure: Split Studio · genre: editorial
 * tone: crafted / editorial · anchor hue: teal (--ink, existing)
 * theme: project tokens (bone paper, teal accent, Fraunces display) —
 *        preserved from global.css per pre-flight; closest catalog analogue
 *        is Almanac (light paper / high-contrast serif / chromatic accent)
 * scope: /personalised/[slug] only. configurator.css is shared with /cart
 *        and /tags/[slug], so this file dresses it from outside rather than
 *        editing it — every selector below is nested under `.pers`, and the
 *        other two pages keep exactly the styling they already had.
 */

.pers {
  /* The scoped 4pt scale and the two surface tones that used to live here are
     project tokens now (tokens.css). They were written when this was the only
     redesigned page and promoting one page's needs to the whole project was a
     bigger claim than that change was entitled to make. The whole site is on
     the system now, so the claim is no longer a claim. */
}

/* ---- Header ---------------------------------------------------------------
   Left-biased, not centred. The measure is capped near 62ch because the
   intro is the only prose on the page, and a full-bleed line of it reads as
   filler. No eyebrow or kicker above the h1 — the nav already says where you
   are, and a numbered label here would be decoration pretending to be
   structure. */

.pers-head {
  max-width: 62ch;
  margin: 0 0 var(--space-xl);
}

.pers-title {
  font-family: var(--font-display);
  /* Clamped rather than fixed: the longest heading here is "Design your pet
     name tag", which at a fixed 3rem wraps badly on a 375px screen. */
  font-size: clamp(1.9rem, 1.35rem + 2.2vw, 2.9rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-md);
  /* A long unbroken word in a heading must break inside itself rather than
     push the whole page sideways. */
  overflow-wrap: anywhere;
  min-width: 0;
}

.pers-intro {
  margin: 0;
  color: var(--ink-3);
  font-size: 1.02rem;
  line-height: 1.62;
}

/* ---- The bench ------------------------------------------------------------
   `.configurator`, `.stage` and `.controls` belong to configurator.css and
   the island's own markup. The rules below re-dress them for this page. */

.pers .configurator {
  gap: var(--space-xl);
  /* One quiet entrance for the bench as a whole, rather than staggering each
     control in. Removed entirely under reduced motion, at the end. */
  animation: pers-settle var(--dur-slow) var(--ease-out) both;
}

@keyframes pers-settle {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Deliberately NOT a card.
   It was one: a raised, bordered, 14px-radius panel sitting beside a stage
   with the identical border and radius. Two equal frames read as two
   equivalent things, and the denser of the two — the one full of inputs and
   carrying the only strong-coloured button — won the page. That is backwards.
   The object is the product; the controls are how you change it. So the stage
   keeps the frame and the controls sit directly on the paper, gaining weight
   only when someone is actually using them. */
.pers .controls {
  gap: var(--space-lg);
  padding: 0 0 0 var(--space-lg);
  border-left: 1px solid var(--line);
}

/* Field labels sit on ink rather than muted. They are the only way through
   the form, and a column of grey labels has no hierarchy at all. */
/* The name is the product, so its input is the one control set at display
   size. Every other choice on the page is secondary to typing it. */
.pers .text-input {
  font-family: var(--font-display);
  font-size: 1.22rem;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background: var(--paper-3);
  transition: border-color 140ms var(--ease-out), box-shadow 140ms var(--ease-out);
}

.pers .text-input:hover:not(:disabled) {
  border-color: var(--ink-3);
}

.pers .text-input:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
  border-color: var(--accent);
}

.pers .chip {
  padding: var(--space-xs) var(--space-sm);
  /* Clickable text must never wrap to a second line: it reads as a layout
     fault and makes the tap target's bounds ambiguous. */
  white-space: nowrap;
  transition: border-color 140ms var(--ease-out), background-color 140ms var(--ease-out);
}

.pers .chip:hover:not(:disabled):not(.chip-on) {
  border-color: var(--ink);
}

/* Hover lifts a swatch slightly, but selection is carried by the ring — which
   is also what a keyboard user sees, so the state is never hover-only. */
.pers .swatch:hover:not(:disabled) {
  transform: translateY(-1px);
}

.pers .swatch-on {
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink);
}

.pers .summary {
  border-top: 1px solid var(--line);
  padding-top: var(--space-md);
  color: var(--ink-3);
  font-size: 0.9rem;
}

.pers .cta {
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-md);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: background-color 140ms var(--ease-out), transform 90ms var(--ease-out);
}

.pers .cta:not(:disabled):hover {
  background: var(--accent-deep);
}

.pers .cta:not(:disabled):active {
  transform: translateY(1px);
}

.pers .cta:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---- How it is made -------------------------------------------------------
   A definition list on hairlines, not three icon tiles. The label/detail pair
   is the Split Studio diptych at row scale: the claim on one side, the
   substance on the other, attention alternating across the gutter. */

.pers-made {
  margin-top: var(--space-2xl);
  padding-top: var(--space-xl);
  border-top: 1px solid var(--line);
}

.pers-made__heading {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 400;
  margin: 0 0 var(--space-lg);
  letter-spacing: -0.01em;
}

.pers-made__list {
  margin: 0;
}

.pers-made__row {
  display: grid;
  /* minmax(0, ...) on both tracks: a long unbroken string in the detail must
     shrink its own track rather than widen the page. */
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: var(--space-lg);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--line);
}

.pers-made__row:last-child {
  border-bottom: 0;
}

.pers-made__label {
  margin: 0;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.pers-made__detail {
  margin: 0;
  /* minmax(0, ...) on the track stops the grid widening, but a single
     unbroken string still overflows its own cell without this. */
  overflow-wrap: anywhere;
  color: var(--ink-3);
  line-height: 1.6;
  max-width: 58ch;
}

.pers-made__foot {
  margin: var(--space-xl) 0 0;
  color: var(--ink-3);
  font-size: 0.88rem;
}

/* ---- Narrow screens -------------------------------------------------------
   The bench collapses to one column and the stage stops being sticky — a
   sticky stage on a short viewport pins the preview on top of the controls
   the customer is reaching for. configurator.css does both of those at
   54rem; this file only has to re-dress what it dresses on wide screens.

   The `.pers .stage { position: static }` that used to sit here is gone on
   purpose. It outranked configurator.css's `position: relative` on
   specificity, which left `.stage-controls` — the rotate buttons, absolutely
   positioned — with no positioned ancestor to anchor to. They still landed in
   the right place, but only because the stage's entrance animation
   incidentally created a containing block while it ran; once the animation
   finished, or under `prefers-reduced-motion` where it never runs at all,
   that accident is not there to rely on. */

@media (max-width: 52rem) {
  .pers .configurator {
    grid-template-columns: minmax(0, 1fr);
  }

  .pers .controls {
    padding: var(--space-lg) 0 0;
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  .pers-made__row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xs);
  }

  .pers-made {
    margin-top: var(--space-2xl);
  }
}

/* ---- Forced colours -------------------------------------------------------
   Windows high-contrast and similar modes strip background-color and
   box-shadow. That is survivable for most of this page — but a swatch has
   nothing except its colour, and its selected state is carried entirely by a
   box-shadow ring, so both vanish at once: the customer sees eight identical
   buttons and no indication which one is chosen.

   `outline` is one of the few properties these modes preserve, so selection is
   restated with one. The stage's frame is restated for the same reason: its
   surface tint and inset sheen both disappear, leaving the object floating on
   an unbounded field. */

@media (forced-colors: active) {
  .pers .swatch-on {
    outline: 3px solid CanvasText;
    outline-offset: 2px;
  }

  .pers .stage {
    border-color: CanvasText;
  }

  .pers .controls {
    border-left-color: CanvasText;
  }
}

/* ---- Reduced motion -------------------------------------------------------
   Spatial motion goes entirely. The colour and border transitions above stay:
   each is under 150ms and carries state rather than decorating it. */

@media (prefers-reduced-motion: reduce) {
  .pers .configurator {
    animation: none;
  }

  .pers .swatch:hover:not(:disabled) {
    transform: none;
  }

  .pers .cta:not(:disabled):active {
    transform: none;
  }
}

/* The price, stated in the page rather than only inside the island.
   Sits under the intro at the top of the page, where someone deciding whether
   to spend five minutes designing something can see the number first. */
.pers .pers-price {
  margin: var(--space-sm) 0 0;
  color: var(--ink-2);
  font-size: var(--text-md);
}

.pers .pers-price strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
