  :root{
    --navy:#0C1530;
    --navy-lift:#14203F;
    --navy-edge:#1F2C4F;
    --sign:#F3F6FB;
    --shield:#CE0E3C;
    --steel:#8E9AB2;
    --stripe:#2E6FD9;

    --display:"Big Shoulders Display","Arial Narrow",Impact,sans-serif;
    --body:"Barlow","Helvetica Neue",Arial,sans-serif;
    --data:"Barlow Condensed","Arial Narrow",Arial,sans-serif;

    --shell:1120px;
    /* The gutters below are the safe-area insets. On a notched iPhone in
       landscape the notch eats into one side of the viewport, and with
       viewport-fit=cover the page paints underneath it - so the horizontal
       padding has to grow by whatever the system reports. max() keeps the
       normal value on every device that reports zero, which is most of them. */
    --pad:max(clamp(20px,5vw,48px), env(safe-area-inset-left), env(safe-area-inset-right));
  }

  *{box-sizing:border-box}

  body{
    margin:0;
    background:var(--navy);
    color:var(--sign);
    font-family:var(--body);
    font-size:17px;
    line-height:1.6;
    -webkit-font-smoothing:antialiased;
    /* iOS inflates text in some reflow situations unless this is pinned, which
       silently breaks a layout tuned at real sizes. */
    -webkit-text-size-adjust:100%;
    /* the default is an opaque grey flash on every tap; this keeps the feedback
       but stops it reading as a rendering glitch on dark panels */
    -webkit-tap-highlight-color:rgba(255,255,255,.08);
  }

  img{max-width:100%}

  .shell{max-width:var(--shell);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}

  .eyebrow{
    font-family:var(--data);font-weight:700;font-size:13px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--steel);margin:0;
  }
  .eyebrow .mark{color:var(--shield)}

  h1,h2,h3{font-family:var(--display);font-weight:800;text-transform:uppercase;text-wrap:balance;margin:0;line-height:.92;letter-spacing:-.01em}
  h1{font-size:clamp(40px,7.4vw,76px)}
  h2{font-size:clamp(30px,4.8vw,50px)}
  h3{font-size:clamp(21px,2.3vw,26px)}

  p{margin:0}
  .lede{font-size:clamp(17px,1.9vw,20px);color:#C4CCDA;max-width:58ch}

  a{color:inherit}

  .seam{
    height:6px;border:0;margin:0;
    background:repeating-linear-gradient(90deg,var(--navy-edge) 0 44px,transparent 44px 76px);
  }

  .btn{
    display:inline-flex;align-items:center;gap:10px;
    font-family:var(--data);font-weight:700;font-size:17px;
    letter-spacing:.09em;text-transform:uppercase;text-decoration:none;
    padding:15px 26px;border-radius:2px;
    transition:transform .15s ease,background-color .15s ease;
  }
  .btn-primary{background:var(--shield);color:#fff;box-shadow:0 10px 26px -14px rgba(206,14,60,.9)}
  .btn-primary:hover{background:#E51648;transform:translateY(-2px)}
  .btn-ghost{background:transparent;color:var(--sign);border:1px solid var(--navy-edge)}
  .btn-ghost:hover{border-color:var(--steel);transform:translateY(-2px)}
  a:focus-visible,button:focus-visible{outline:3px solid var(--stripe);outline-offset:3px}

  /* ---- masthead (same three-track grid as the home page) ---- */
  .nav{
    display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
    gap:clamp(12px,2.2vw,32px);
    padding:14px var(--pad);border-bottom:1px solid var(--navy-edge);
  }
  .nav-brand{display:flex;align-items:center;gap:13px;text-decoration:none;justify-self:start}
  .nav-brand img{width:clamp(46px,3.8vw,56px);height:auto;display:block}
  .nav-brand b{font-family:var(--display);font-weight:800;font-size:clamp(16px,1.35vw,21px);line-height:1;text-transform:uppercase;white-space:nowrap}
  .nav-right{display:flex;align-items:center;gap:clamp(10px,1.4vw,18px);justify-self:end}
  .nav-links{display:flex;gap:clamp(14px,1.8vw,30px);justify-self:center}
  .nav-links a{
    font-family:var(--data);font-size:13px;font-weight:600;letter-spacing:.14em;
    text-transform:uppercase;color:var(--steel);text-decoration:none;transition:color .2s ease;
  }
  .nav-links a:hover{color:var(--sign)}
  .nav-links a[aria-current="page"]{color:var(--sign);border-bottom:1px solid var(--shield);padding-bottom:3px}
  .nav-pill{
    font-family:var(--data);font-size:11px;font-weight:600;letter-spacing:.14em;
    text-transform:uppercase;color:var(--steel);
    border:1px solid var(--navy-edge);border-radius:999px;padding:7px 14px;flex:none;
  }
  .nav-cta{
    font-family:var(--data);font-size:13px;font-weight:700;letter-spacing:.1em;
    text-transform:uppercase;background:var(--shield);color:#fff;text-decoration:none;
    border-radius:999px;padding:10px 18px;flex:none;transition:background-color .2s ease;
  }
  .nav-cta:hover{background:#E51648}

  .promo{background:var(--shield);color:#fff}
  .promo-in{
    display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
    gap:6px 14px;padding:9px 0;text-align:center;
    font-family:var(--data);font-weight:600;font-size:12.5px;
    letter-spacing:.12em;text-transform:uppercase;
  }
  .promo-in a{color:#fff;text-decoration:underline;text-underline-offset:3px}

  /* ---- page hero ----
     Deliberately not the home page's full-viewport split: this is an interior
     page and the colour picker is the reason anyone opened it, so the hero is
     a band that gets out of the way. */
  .ph{
    position:relative;overflow:hidden;
    border-bottom:1px solid var(--navy-edge);
    min-height:clamp(300px,42vh,430px);
    display:flex;align-items:flex-end;
  }
  .ph-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 45%}
  /* the scrim is what keeps the headline legible over whatever photo lands
     here - it must survive a light cover photo as well as a dark one */
  .ph::after{
    content:"";position:absolute;inset:0;
    background:linear-gradient(180deg,rgba(12,21,48,.30) 0%,rgba(12,21,48,.72) 55%,rgba(12,21,48,.96) 100%);
  }
  .ph-in{position:relative;z-index:1;width:100%;padding-top:60px;padding-bottom:clamp(28px,4vw,44px)}
  .ph h1{margin-top:10px}
  .ph .lede{margin-top:16px}
  .crumb{
    display:inline-flex;align-items:center;gap:8px;
    font-family:var(--data);font-size:13px;font-weight:600;letter-spacing:.14em;
    text-transform:uppercase;color:var(--steel);text-decoration:none;
    margin-bottom:18px;transition:color .2s ease;
  }
  .crumb:hover{color:var(--sign)}
  .crumb svg{width:15px;height:15px}

  section{padding-top:clamp(52px,7vw,88px);padding-bottom:clamp(52px,7vw,88px)}
  .sec-head{margin-bottom:clamp(26px,3.5vw,40px)}
  .sec-head h2{margin-top:10px}
  .sec-head .lede{margin-top:14px}

  /* ---- spec cards ---- */
  .specs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(16px,2.4vw,26px)}
  .spec{
    background:var(--navy-lift);border:1px solid var(--navy-edge);
    border-top:4px solid var(--shield);border-radius:4px;
    padding:clamp(24px,3.2vw,36px);display:flex;flex-direction:column;
  }
  .spec-tag{
    align-self:flex-start;background:var(--stripe);color:#fff;
    font-family:var(--data);font-weight:700;font-size:12px;letter-spacing:.16em;
    text-transform:uppercase;padding:6px 12px;border-radius:2px;
  }
  .spec h3{margin-top:16px}
  .spec-size{
    font-family:var(--display);font-weight:800;line-height:.88;
    font-size:clamp(58px,9vw,96px);margin-top:10px;
  }
  .spec-size .u{color:var(--shield);font-size:.45em;margin-left:.06em;vertical-align:super}
  .spec dl{margin:22px 0 0;display:flex;flex-direction:column;gap:2px}
  .spec .srow{
    display:flex;justify-content:space-between;align-items:baseline;gap:16px;
    padding:13px 0;border-bottom:1px solid var(--navy-edge);
  }
  .spec .srow:first-child{border-top:1px solid var(--navy-edge)}
  .spec dt{font-family:var(--data);font-size:13px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--steel);margin:0}
  .spec dd{margin:0;font-family:var(--display);font-weight:700;font-size:clamp(19px,2vw,24px);text-transform:uppercase;line-height:1;text-align:right}
  .spec p{margin-top:20px;font-size:15.5px;color:#A6B0C6}

  /* ---- the configurator ---- */
  .viz{display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(20px,3vw,30px)}

  .stage{
    background:var(--navy-lift);border:1px solid var(--navy-edge);
    border-radius:16px;overflow:hidden;
  }
  #scene{
    display:block;width:100%;
    height:clamp(340px,48vw,580px);
    cursor:grab;
    /* pan-y, not none: a vertical swipe has to stay a page scroll, or the
       reader is stuck inside the model with no way past it */
    touch-action:pan-y;
    -webkit-user-select:none;user-select:none;
  }
  #scene:active{cursor:grabbing}
  #scene:focus-visible{outline:3px solid var(--stripe);outline-offset:-3px}

  .no3d-msg{display:none;padding:28px clamp(16px,2.2vw,24px);color:#A6B0C6;font-size:15px}
  .stage.no-3d #scene{display:none}
  .stage.no-3d .no3d-msg{display:block}

  .readout{
    display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    padding:16px clamp(16px,2.2vw,24px);
    border-top:1px solid var(--navy-edge);background:rgba(12,21,48,.5);
  }
  .readout-name{
    font-family:var(--data);font-weight:700;font-size:14px;
    letter-spacing:.1em;text-transform:uppercase;color:var(--sign);
  }
  .readout-hint{
    margin-left:auto;font-family:var(--data);font-size:12.5px;font-weight:600;
    letter-spacing:.14em;text-transform:uppercase;color:var(--steel);text-align:right;
  }
  .hint-tap{display:none}
  @media (hover:none),(pointer:coarse){
    .hint-hover{display:none}
    .hint-tap{display:inline}
  }

  /* One row per part. Rows rather than one long strip because the question is
     not "which colour" but "which colour for which piece", and a single strip
     cannot say that. */
  .parts{display:flex;flex-direction:column;gap:clamp(16px,2.2vw,22px)}
  .prow{
    display:grid;grid-template-columns:minmax(120px,150px) minmax(0,1fr);
    gap:clamp(12px,2vw,22px);align-items:center;
    padding-bottom:clamp(14px,2vw,18px);border-bottom:1px solid var(--navy-edge);
  }
  .prow:last-child{border-bottom:0;padding-bottom:0}
  .prow-label{
    margin:0;font-family:var(--data);font-weight:700;font-size:13px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--steel);
  }
  .prow-opts{display:flex;flex-wrap:wrap;gap:10px}

  .opt{
    display:flex;align-items:center;gap:9px;
    padding:7px 14px 7px 7px;border-radius:999px;cursor:pointer;
    background:var(--navy-lift);border:1px solid var(--navy-edge);
    color:var(--steel);
    font-family:var(--data);font-size:12.5px;font-weight:600;
    letter-spacing:.1em;text-transform:uppercase;
    transition:border-color .2s ease,color .2s ease,background-color .2s ease;
  }
  .opt-sw{
    width:22px;height:22px;border-radius:50%;flex:none;
    background:var(--c);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
  }
  .opt:hover{border-color:#33426E;color:var(--sign)}
  .opt[aria-pressed="true"]{
    border-color:var(--shield);color:var(--sign);background:#1B2A50;
  }

  .note{
    margin-top:clamp(22px,3vw,30px);padding:18px 20px;
    border:1px solid var(--navy-edge);border-left:3px solid var(--stripe);
    border-radius:4px;background:var(--navy-lift);
    font-size:15px;color:#A6B0C6;
  }

  /* ---- closing call band ---- */
  .band{
    background:var(--navy-lift);border:1px solid var(--navy-edge);
    border-top:4px solid var(--shield);
    padding:clamp(28px,4vw,48px);
    display:flex;gap:clamp(20px,3vw,40px);align-items:center;flex-wrap:wrap;
  }
  .band div{flex:1 1 320px;min-width:0}
  .band h2{margin-bottom:12px}
  /* the copy column flexes, the button column hugs its content */
  .band-cta{flex:0 1 auto}

  footer{border-top:1px solid var(--navy-edge);padding:34px 0 44px}
  .foot{display:flex;flex-wrap:wrap;gap:16px 28px;justify-content:space-between;align-items:center}
  .foot p{font-family:var(--data);font-size:14px;letter-spacing:.08em;text-transform:uppercase;color:var(--steel)}
  .foot a{color:var(--steel);text-decoration:none}
  .foot a:hover{color:var(--sign)}

  /* ---- touch targets ----
     Measured on a 375px viewport: the nav row came out 21px tall, the
     breadcrumb 21px and the footer links 17px, against a 44px minimum. These
     are all inline text, so the fix is vertical padding and a min-height
     rather than a bigger type size, which would wreck the layout. */
  @media (pointer:coarse){
    .nav-links a{padding:12px 2px;min-height:44px;display:inline-flex;align-items:center}
    .nav-brand{min-height:48px}
    .nav-cta{padding:13px 20px}
    .foot a{padding:13px 0;display:inline-block}
    .promo-in a{padding:13px 4px;display:inline-block}
    .crumb{padding:12px 4px 12px 0;margin-bottom:8px;min-height:44px}
    /* the option pills came out 38px against the 44 minimum */
    .opt{min-height:46px;padding-top:9px;padding-bottom:9px}
  }

  @media (max-width:900px){
    .nav-links,.nav-pill{display:none}
    .specs{grid-template-columns:minmax(0,1fr)}
  }

  @media (max-width:640px){
    .nav{
      grid-template-columns:minmax(0,1fr) auto;
      grid-template-areas:"brand cta" "links links";
      row-gap:11px;padding:12px var(--pad);
    }
    .nav-brand{grid-area:brand;min-width:0;gap:11px}
    .nav-brand img{width:42px}
    .nav-brand b{font-size:clamp(14px,3.9vw,18px)}
    .nav-right{grid-area:cta}
    /* Wraps, because the row outgrew the phone. The home masthead carries six
       links now (Floors was added with the floors page) and at 375px they came
       to 439px against a 375px viewport - the page scrolled sideways by 32px,
       which reads as a broken layout rather than as a long menu. Wrapping to a
       second line costs a few pixels of masthead height and keeps every link
       reachable; dropping one would have hidden a section instead. */
    .nav-links{grid-area:links;display:flex;flex-wrap:wrap;justify-content:center;gap:6px 18px}
    .nav-pill{display:none}
    .nav-cta{padding:12px 17px;font-size:13px}
    .promo-in{font-size:11.5px;letter-spacing:.08em;padding:8px 0;gap:4px 12px}

    .readout-hint{margin-left:0;text-align:left;width:100%}
    .spec dd{font-size:18px}
  }

  @media (max-width:520px){
    .btn{width:100%;justify-content:center}
  }

  /* ---- hero framing ----
     `.ph-flat`, the text-only header that stood here while there was no floor
     photograph, is gone: there is one now and this page is the same as the other
     two again.

     The photo is portrait, shot at floor level, and the hero box is neither -
     about 1.3:1 on a phone and nearly 4:1 on a wide desktop. As on the stairs
     page the file stays uncropped and `object-position` picks the band. */
  .ph-floor .ph-img{object-position:center 55%}

  /* The same measurement the stairs hero needed, and the same answer. Sampled
     against the brightest decile of the photo actually sitting behind them, the
     breadcrumb came out at 1.5:1 and the eyebrow at 1.9:1 - both far under the
     4.5:1 that 13px text needs. They sit high in the hero where the scrim is
     thinnest, and this photo is daylight on a pale wall up there.

     White fixes it. Darkening the scrim instead would take about 0.85 alpha at
     the top, which erases the photograph to rescue two labels. The headline and
     lede already cleared it at 7.9:1 and 7.7:1 and are left alone. */
  .ph-floor .crumb,
  .ph-floor .eyebrow{color:#fff}
  .ph-floor .crumb:hover{color:var(--sign)}

  /* White alone left the breadcrumb at 4.16:1 on a desktop - close, and still
     under. It sits highest in the hero, where the shared scrim is thinnest at
     0.30, and on a wide screen the band showing there is the daylit end of the
     hall rather than the floor.

     0.42 at the top instead. Swept against the real pixels, 0.36 is the first
     value that passes and 0.42 leaves about half a stop of margin so rounding
     or a different pixel ratio cannot tip it back under. The rest of the
     gradient is untouched, and the top of a hero is mostly behind the masthead
     anyway, so the photograph loses nothing you were looking at. */
  .ph-floor::after{
    background:linear-gradient(180deg,rgba(12,21,48,.42) 0%,rgba(12,21,48,.72) 55%,rgba(12,21,48,.96) 100%);
  }

  /* ---- the four kinds of option chip ----
     Species is the only choice here with a colour. The other three are a
     dimension, a geometry and a surface property, and a coloured dot for any of
     them would be decoration standing where information should be. */

  /* Board width: vertical joints at the spacing of the boards. The chip is 22px
     across, so the three real widths scaled honestly would be about 1, 1.6 and
     2.2px apart and indistinguishable - these are spread to stay legible while
     keeping the order and the sense of the gap. */
  .opt-sw--rule{
    border-radius:3px;
    background:repeating-linear-gradient(90deg,
      #C7A87E 0 calc(var(--pitch) - 1px),
      #5E4632 calc(var(--pitch) - 1px) var(--pitch));
  }

  /* Layout: a scrap of the pattern itself. */
  .opt-sw--icon{
    border-radius:3px;background:#1B2A50;color:var(--steel);
    display:flex;align-items:center;justify-content:center;
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);
  }
  .opt-sw--icon svg{width:17px;height:17px;display:block}
  .opt:hover .opt-sw--icon,
  .opt[aria-pressed="true"] .opt-sw--icon{color:var(--sign)}

  /* Finish: the same board with a specular highlight that sharpens with the
     sheen. Matte has none, semi-gloss has a hard one - which is exactly the
     difference the 3D model shows when you switch between them. */
  .opt-sw--sheen{
    background:
      radial-gradient(circle at 33% 27%,
        rgba(255,255,255,calc(var(--gloss) * .95)) 0 11%,
        rgba(255,255,255,0) 46%),
      #C7A87E;
  }

  @media (max-width:640px){
    /* label above its swatches: side by side, a 120px label column leaves the
       options about 190px wide and they wrap one per line */
    .prow{grid-template-columns:minmax(0,1fr);gap:10px;align-items:start}
    #scene{height:clamp(300px,64vw,420px)}
    .readout-hint{margin-left:0;text-align:left;width:100%}
  }
