/* Two Brothers Tile — the pieces artsy does not ship.
   Artsy is a design-vault template built for design review: call/text CTAs, no form,
   no FAQ. This site is a lead-capture site, so the quote form IS the product and the
   FAQ blocks carry FAQPage schema. Everything below is written in artsy's own idiom:
   3px ink borders, --radius 2px, hard offset shadows with zero blur, uppercase
   display type, shear on pills. No new tokens - artsy.css owns the palette. */

/* ---------- QUOTE FORM ---------- */
.bid-card {
  background: var(--paper);
  color: var(--body-text);   /* MUST be set: .hero sets a near-white colour for the dark
                                hero, and this card is white. Without this reset, anything
                                inside with no colour of its own is white on white. */
  border: 3px solid var(--ink);
  border-radius: var(--radius);
  box-shadow: var(--pop) var(--pop) 0 0 var(--primary);
  padding: 26px 24px 24px;
}
.band--ink .bid-card { box-shadow: var(--pop) var(--pop) 0 0 var(--primary); }
.bid-card h2, .bid-card h3 { margin: 0 0 4px; color: var(--ink); }
.bid-card .lead { margin: 0 0 18px; font-size: 0.95rem; color: var(--muted-text); }

.field { display: block; margin-bottom: 14px; }
.field > span, .field label {
  display: block;
  font-family: var(--font-display);
  font-weight: 900; font-size: 0.72rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink); margin-bottom: 6px;
}
.field .hint { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--muted-text); }
.field input, .field select, .field textarea {
  width: 100%;
  font: inherit; font-size: 1rem;
  color: var(--ink); background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  padding: 11px 12px;
  appearance: none;
}
/* appearance:none strips the native arrow; without putting one back a select is
   indistinguishable from a text input and the field reads as broken. */
.field select {
  padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%),
                    linear-gradient(135deg, var(--ink) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.field textarea { min-height: 104px; resize: vertical; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: 3px solid var(--primary); outline-offset: 2px; border-color: var(--ink);
}
/* main.js toggles .invalid on the .field wrapper - it does NOT set aria-invalid.
   Keying off the wrong attribute meant the red border never appeared and, worse,
   .err defaulted to display:block so every field showed its error text permanently. */
.field.invalid input, .field.invalid select, .field.invalid textarea { border-color: #B42318; }
.field .err { display: none; margin-top: 5px; font-size: 0.8rem; font-weight: 700; color: #B42318; }
.field.invalid .err { display: block; }

.consent { display: flex; gap: 10px; align-items: flex-start; margin: 4px 0 16px; }
.consent input { width: 20px; height: 20px; flex: 0 0 auto; margin-top: 2px; accent-color: var(--primary); }
.consent span, .consent label { font-size: 0.8rem; line-height: 1.45; color: var(--muted-text); cursor: pointer; }

.form-foot { margin: 12px 0 0; font-size: 0.78rem; color: var(--muted-text); }
.form-success {
  border: 3px solid var(--ink); border-radius: var(--radius);
  background: var(--primary); color: var(--on-primary);
  padding: 16px 18px; font-weight: 800;
}

/* ---------- FAQ ---------- */
.faq { display: grid; gap: 0; border-top: 3px solid var(--ink); }
.faq details { border-bottom: 3px solid var(--ink); background: var(--paper); }
.band--ink .faq { border-color: rgba(255,255,255,.22); }
.band--ink .faq details { background: transparent; border-color: rgba(255,255,255,.22); }
.faq summary {
  cursor: pointer; list-style: none;
  padding: 18px 44px 18px 2px; position: relative;
  font-family: var(--font-display); font-weight: 900;
  font-size: 1.02rem; letter-spacing: var(--tracking-display);
  color: var(--ink);
}
.band--ink .faq summary { color: var(--on-ink); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 50%;
  width: 14px; height: 3px; background: var(--primary);
  transform: translateY(-50%);
  box-shadow: 0 0 0 0 transparent;
}
.faq summary::before {
  content: ""; position: absolute; right: 13.5px; top: 50%;
  width: 3px; height: 14px; background: var(--primary);
  transform: translateY(-50%);
  transition: opacity .16s ease;
}
.faq details[open] summary::before { opacity: 0; }
.faq summary:focus-visible { outline: 3px solid var(--primary); outline-offset: -3px; }
.faq p { margin: 0 0 18px; padding-right: 44px; max-width: 68ch; }

/* ---------- BREADCRUMB / RELATED / PROSE ---------- */
.breadcrumb {
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted-text); margin: 0 0 14px;
}
.breadcrumb a { color: inherit; }
.band--ink .breadcrumb, .hero .breadcrumb { color: var(--on-ink-muted); }

.rel-links { display: flex; flex-wrap: wrap; gap: 10px; padding: 0; margin: 22px 0 0; list-style: none; }
.rel-links a {
  display: inline-block;
  border: 2px solid var(--ink); border-radius: var(--radius);
  padding: 7px 13px; text-decoration: none; color: var(--ink);
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.76rem; letter-spacing: 0.06em; text-transform: uppercase;
  transform: skewX(calc(var(--shear) * -1));
}
.rel-links a > span { display: inline-block; transform: skewX(var(--shear)); }
.rel-links a:hover { background: var(--primary); border-color: var(--ink); }

.prose-narrow { max-width: 68ch; }
.prose-narrow h1 { margin-bottom: 18px; }
.prose-narrow p { margin: 0 0 16px; }

.lang-switch { font-size: 0.78rem; }

/* ---------- SERVICE / LOCATION SUPPORT ---------- */
.job-list { list-style: none; padding: 0; margin: 0; }
.job-list li {
  display: flex; justify-content: space-between; gap: 18px;
  padding: 12px 0; border-bottom: 2px solid var(--line);
}
.band--ink .job-list li { border-color: rgba(255,255,255,.18); }
.job-list b { font-weight: 800; }

.callout {
  border-left: 6px solid var(--primary);
  background: var(--paper-soft);
  padding: 14px 18px; margin: 22px 0;
}
.band--ink .callout { background: var(--ink-soft); }

@media (max-width: 720px) {
  .bid-card { padding: 20px 18px; box-shadow: 3px 3px 0 0 var(--primary); }
  .faq p { padding-right: 0; }
}

/* ---------- leftovers from the generator's own markup ---------- */
.brand-logo { display: inline-block; vertical-align: middle; margin-right: 8px; }
.job-list .job { font-weight: 700; color: inherit; }
.job-list .price { white-space: nowrap; font-weight: 900; color: var(--accent-ink); }
.band--ink .job-list .price { color: var(--primary); }
.sub { margin: 0 0 18px; color: var(--muted-text); }
.band--ink .sub { color: var(--on-ink-muted); }
.work-slide { margin: 0; border: 3px solid var(--ink); border-radius: var(--radius); overflow: hidden; }
.work-slide img { display: block; width: 100%; height: auto; }

/* ---------- HERO: form lives inside it, and it is shorter ----------
   artsy ships .hero .wrap at 110px/96px block padding with a single copy column.
   With the quote card in the hero that is far too tall, so the padding comes down
   and the wrap becomes a two-column grid. The wedge still cuts the ink panel on the
   diagonal behind both columns. */
.hero .wrap { padding-block: 56px 52px; }

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(330px, 430px);
  gap: 44px;
  align-items: start;
}
.hero__copy { max-width: none; }
.hero .lead { max-width: 32rem; margin-bottom: 18px; }
.hero .rule { margin-bottom: 16px; }

/* the ghost watermark is sized for a full-width hero; rein it in beside a form */
.hero .ghost { font-size: clamp(2.6rem, 7vw, 5rem); }

/* MOBILE HORIZONTAL SCROLL. .ghost is the decorative watermark, sized
   clamp(3.5rem, 11vw, 8.5rem). On a 375px phone the 11vw term loses to the 3.5rem floor,
   so it renders at 56px, and a single unbreakable word at that size is wider than the
   column: "Waterproofing," measured 477px inside a 331px wrap. That pushed the document
   to 499px and gave every phone a sideways scrollbar.
   The element is aria-hidden decoration, so clip the bleed instead of reflowing it.
   overflow: clip rather than hidden, so no scroll container is created. */
.ghost { max-width: 100%; overflow: clip; }


/* compact trust list so the hero does not grow a third block of height */
.ticks--compact { margin: 0 0 18px; }
.ticks--compact li { margin-bottom: 5px; font-size: 0.92rem; }

/* hero card sizing lives in one place, below, under HERO FITS THE VIEWPORT */

@media (max-width: 980px) {
  .hero__grid { grid-template-columns: 1fr; gap: 30px; }
  .hero .wrap { padding-block: 44px 40px; }
  .hero .bid-card { max-width: 460px; }
}

/* ---------- HERO FITS THE VIEWPORT ----------
   Target: header + hero == one screen, no scroll to reach the form's submit button.
   svh (not vh) so mobile browser chrome does not push the bottom off-screen. */
:root { --header-h: 70px; }

.hero {
  min-height: calc(100svh - var(--header-h));
  display: flex;
  align-items: center;
}
.hero .wrap { width: 100%; padding-block: 30px; }

/* h1 must not eat the screen on a laptop */
.hero h1 { font-size: clamp(1.9rem, 3.6vw, 3.1rem); line-height: 1.06; margin: 0 0 14px; }
.hero .ghost { font-size: clamp(2.2rem, 5.4vw, 4rem); }
.hero .lead { font-size: 1rem; margin-bottom: 14px; }
.hero .rule { height: 5px; margin-bottom: 13px; }

/* trust lines on ONE row instead of three stacked */
.ticks--compact { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0 0 14px; padding: 0; }
.ticks--compact li { margin: 0; font-size: 0.86rem; }

/* Pair the short fields so the card is 3 rows, not 5. Names come from the generator's
   own wrap- ids, so no markup change is needed. */
.hero .bid-card form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 12px;
  row-gap: 10px;
}
/* row-gap owns the vertical rhythm now; per-field margins would double it up */
.hero .bid-card .field { margin-bottom: 0; }
.hero .bid-card #wrap-details,
.hero .bid-card .consent,
.hero .bid-card button,
.hero .bid-card .form-foot { grid-column: 1 / -1; }

.hero .bid-card { padding: 18px 18px 16px; }
.hero .bid-card h2 { font-size: 1.12rem; margin-bottom: 2px; }
.hero .bid-card .sub { font-size: 0.83rem; margin-bottom: 12px; }
.hero .bid-card .field > span,
.hero .bid-card .field label { font-size: 0.66rem; margin-bottom: 4px; }
.hero .bid-card .field input,
.hero .bid-card .field select,
.hero .bid-card .field textarea { padding: 8px 10px; font-size: 0.95rem; }
.hero .bid-card .field textarea { min-height: 58px; }
.hero .bid-card .consent { margin: 2px 0 2px; align-items: center; }
.hero .bid-card .consent input { width: 18px; height: 18px; margin-top: 0; }
.hero .bid-card .consent span,
.hero .bid-card .consent label { font-size: 0.72rem; line-height: 1.35; }
.hero .bid-card .btn--lg { padding: 11px 18px; font-size: 0.86rem; }
.hero .bid-card .form-foot { margin-top: 8px; font-size: 0.72rem; }

/* Short laptops: give back the scroll rather than clipping the submit button. */
@media (max-height: 700px) {
  .hero { min-height: 0; }
  .hero .wrap { padding-block: 26px; }
  /* the badge hangs 74px into the hero; without the min-height slack the copy would
     collide with it, so the first column starts below the overhang instead. */
  .hero__copy { padding-top: 58px; }
}
@media (max-width: 980px) {
  .hero { min-height: 0; }
  .hero .bid-card form { grid-template-columns: 1fr; }
}

/* ---------- FOOTER SITS IN FRONT OF THE TILTED CTA BAND ----------
   .band--tilt carries z-index:1 and negative margins so neighbours tuck under the
   wedge. The footer had no stacking context at all, so the sheared ink band painted
   OVER the top of it and sliced the wordmark in half. Giving the footer its own
   layer puts the wedge behind it, where it reads as a diagonal edge instead of a
   clipping mask. */
.site-footer { position: relative; z-index: 2; }

/* With the band behind, the old 170px clearance is just a void. Enough room for the
   diagonal to read, not enough to open a dead gap. */
.band--tilt + .site-footer,
.band--tilt-a + .site-footer { padding-top: 96px; }

/* the wordmark wraps in the footer column; keep the halves on one line where it fits */
.site-footer .brand { font-size: 1.05rem; line-height: 1.25; }

/* ---------- THEME: "brothers" — sampled from the transparent lockup ----------
   Values pulled out of the logo PNG by hue/value bucket, then every foreground on
   background pairing checked against WCAG AA. One pairing failed on the first pass:
   the logo's own mid-green #1E8400 as TEXT on paper-soft came to 4.45, just under.
   It is #1E8200 here, two steps darker, which clears 4.57 and still reads as the
   logo green. The logo colour is right for ink and fills; it was not right for text.

     #60C600  the lime of the wordmark and the mascot
     #1E8200  the mid green, as TEXT only
     #0A0F0A  near-black, from the badge outline (logo is pure #000000; softened a hair
              so large dark surfaces do not read as a void)
     #E9EDE9  the chrome of "TWO", kept for rules and borders

   artsy's contract: --on-primary is INK, never white. 8.82:1 here. */
[data-theme="brothers"] {
  --ink: #0A0F0A;
  --ink-soft: #17211A;
  --primary: #60C600;
  --primary-dark: #4EA300;
  --accent-ink: #1E8200;
  --paper: #FFFFFF;
  --paper-soft: #F3F7F2;
  --line: #DCE4DA;
  --body-text: #2E382E;
  --muted-text: #5C665C;
  --steel: #E9EDE9;
  --ghost: rgba(96, 198, 0, 0.16);
  --ghost-on-paper: rgba(10, 15, 10, 0.07);
}

/* ---------- BRAND MARK ----------
   The lockup is a near-square badge (1.42:1) with the wordmark inside it, so it needs
   real height to stay legible - a 34px strip would reduce "TILE INSTALLATION" to mush. */
.brand { display: inline-flex; align-items: center; gap: 10px; }
.brand-logo { display: block; height: 54px; width: auto; flex: 0 0 auto; }
.brand-words { display: inline-block; }
.site-header { padding: 10px 0; }
.site-footer .brand-logo { height: 76px; }
:root { --header-h: 70px; }
@media (max-width: 560px) { .brand-logo { height: 42px; } }

/* ---------- BRAND STRIP UNDER THE HERO ----------
   The badge gets its own shallow band where it can be read, instead of being crushed
   into the header bar. Flat band, so the tilt sequence is untouched. */
.brand-band { padding: 26px 0 22px; border-bottom: 3px solid var(--ink); }
.brand-band .wrap { display: flex; align-items: center; gap: 26px; }
.brand-band__mark { display: block; height: 104px; width: auto; flex: 0 0 auto; }
.brand-band__rule { flex: 1 1 auto; height: 3px; background: var(--line); }
.brand-band__line {
  margin: 12px 0 0; text-align: center;
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.74rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted-text);
}
@media (max-width: 700px) {
  .brand-band { padding: 20px 0 16px; }
  .brand-band .wrap { gap: 14px; }
  .brand-band__mark { height: 74px; }
}

/* ---------- HEADER ----------
   The wide diamond badge replaces the text wordmark up top. The CTA cluster was three
   competing elements on a dark bar - a language switch pointing at pages that do not
   exist, a long outline button holding the phone number, and the real CTA. Now it is
   one button, with the phone as a link beside it. */
.site-header { padding: 12px 0; overflow: visible; }
.site-header .wrap { display: flex; align-items: center; gap: 26px; }
.site-header .nav { margin-left: auto; }

/* The badge deliberately OUTGROWS the header bar and hangs over the hero. The anchor
   keeps a short fixed height so the header does not grow with it; the image overflows
   that box and the negative bottom margin decides how far it breaks the line.
   .site-header already carries z-index:50, so it paints over the hero cleanly. */
.site-header .brand {
  height: 46px;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  position: relative;
  z-index: 2;
}
.brand-mark {
  display: block;
  height: 152px;
  width: auto;
  flex: 0 0 auto;
  margin: 0 0 -74px;            /* hangs below the bar, over the hero */
  filter: drop-shadow(0 8px 0 rgba(0, 0, 0, 0.35));
}

.header-cta { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; }

.header-phone {
  display: inline-flex; align-items: center; gap: 7px;
  color: var(--on-ink); text-decoration: none;
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.86rem; letter-spacing: 0.02em;
  white-space: nowrap;
}
.header-phone svg { color: var(--primary); flex: 0 0 auto; }
.header-phone:hover { color: var(--primary); }
.header-phone:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; }

/* the header button is small, so the 4px hard shadow reads as grime rather than depth */
.header-cta .btn--primary { --pop: 3px; padding: 10px 18px; font-size: 0.78rem; }

@media (max-width: 900px) {
  .site-header .wrap { gap: 14px; }
  .site-header .brand { height: 40px; }
  .brand-mark { height: 112px; margin-bottom: -54px; }
  .header-phone span { display: none; }
  .header-phone { padding: 8px; }
  .header-phone svg { width: 20px; height: 20px; }
}
@media (max-width: 560px) {
  .site-header .brand { height: 34px; }
  .brand-mark { height: 86px; margin-bottom: -40px; }
  .header-cta .btn--primary { padding: 9px 13px; font-size: 0.72rem; }
}

/* ---------- BUTTON UTILITIES THE GENERATOR USES ----------
   The generator emits btn--block and btn--lg (inherited vocabulary); artsy defines
   neither, so the form's submit button was rendering as a bare base .btn - no accent
   fill, not full width. That was the single sloppiest thing on the card. */
.btn--block { display: flex; width: 100%; }
.btn--lg { padding: 14px 22px; font-size: 0.95rem; }
.bid-card .btn--block { margin-top: 2px; }

/* ---------- SERVICE OPENING SECTION (band--lede) ----------
   A display position, centred. base.css sets --measure-display to 16ch, "short enough to
   land in one breath"; the supporting sentence sits at heading measure so the two read as
   a pair rather than one wide slab. Centred text needs its measure PLUS margin-inline:auto,
   otherwise max-width pins it left and the centring does nothing.

   The tick list is the deliberate exception: the BLOCK is centred, the items stay
   left-aligned, because centred list items with leading markers rag on both edges. */
.band--lede { text-align: center; }

.band--lede .display {
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  line-height: 1.03;
  letter-spacing: var(--tracking-display);
  max-width: 18ch;
  margin: 0 auto 16px;
  text-wrap: balance;
}
.band--lede .lead {
  font-size: 1.04rem;
  line-height: 1.6;
  max-width: var(--measure-heading);
  margin: 0 auto;
  text-wrap: pretty;
}

.band--lede .ticks {
  display: inline-block;
  text-align: left;
  margin: 24px auto 0;
  padding: 0;
}
.band--lede .ticks li { margin-bottom: 8px; }

/* the photograph is evidence, not a hero: it sits under the type without out-weighing it */
.band--lede .frame { max-width: 520px; margin: 30px auto 0; }

.frame {
  display: flex; flex-direction: column;
  border: 3px solid var(--ink); border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--pop) var(--pop) 0 0 var(--primary);
}
.frame img { display: block; width: 100%; height: auto; }

@media (max-width: 700px) {
  .band--lede .display { font-size: clamp(1.75rem, 7vw, 2.4rem); max-width: 16ch; }
  .band--lede .frame { max-width: 100%; }
}
/* ---------- TRUST BAR ----------
   Section three. Scannable in about a second: label above, fact below, hard rules
   between. Flat band, so the tilt sequence is untouched. */
.trust-bar { padding: 22px 0; border-block: 3px solid var(--ink); }
.trust-bar__list {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 0; list-style: none; margin: 0; padding: 0;
}
.trust-bar__list li {
  flex: 1 1 190px;
  padding: 6px 22px;
  border-left: 2px solid var(--line);
  text-align: center;
}
.trust-bar__list li:first-child { border-left: 0; }
.trust-bar__k {
  display: block;
  font-family: var(--font-display); font-weight: 900;
  font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent-ink); margin-bottom: 4px;
}
.trust-bar__v {
  display: block;
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.94rem; line-height: 1.3; color: var(--ink);
}
@media (max-width: 760px) {
  .trust-bar__list li { flex: 1 1 46%; border-left: 0; padding: 8px 10px; }
  .trust-bar__v { font-size: 0.86rem; }
}

/* ---------- RECENT WORK GRID ----------
   Photos of finished rooms, so they carry themselves: hard ink border and the accent
   offset shadow artsy uses everywhere, no captions competing with the images. The shots
   are a mix of portrait and landscape, so a fixed aspect keeps the grid from raggedness. */
.work-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; margin-top: 30px; }
.work-slide {
  margin: 0;
  border: 3px solid var(--ink);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--pop) var(--pop) 0 0 var(--primary);
  background: var(--ink-soft);
}
.work-slide img { display: block; width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
@media (max-width: 900px) { .work-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; } }
@media (max-width: 560px) { .work-grid { grid-template-columns: 1fr; } }

/* ---------- COMMERCIAL BAND ----------
   Flat ink so it reads as a separate offer from the residential grid above, without
   adding a third tilt. Centred like the service lede, and the shots are all portrait,
   so a fixed 3:4 keeps the row even. */
.commercial { text-align: center; }
.commercial .display { max-width: 20ch; margin: 0 auto 16px; color: var(--on-ink); text-wrap: balance; }
.commercial .lead { max-width: var(--measure-body); margin: 0 auto; color: var(--on-ink-muted); }
.commercial-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 30px; }
.commercial-grid figure {
  margin: 0; border: 3px solid var(--primary); border-radius: var(--radius);
  overflow: hidden; background: var(--ink-soft);
}
.commercial-grid img { display: block; width: 100%; height: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
@media (max-width: 760px) {
  .commercial-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .commercial-grid figure:last-child { display: none; }
}
/* phone numbers in the trust bar are tappable */
a.trust-bar__v { text-decoration: none; }
a.trust-bar__v:hover { color: var(--accent-ink); }

/* ---------- MOBILE MENU ----------
   artsy.css sets `.nav { display: none }` under 900px and ships no replacement, so a
   phone visitor had NO navigation at all: the header offered only the call icon and the
   quote button. This adds the missing control.
   The panel is positioned against .site-header, which already carries position:relative
   and z-index:50, so it paints over the hero without a new stacking context. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;          /* 44px is the minimum comfortable touch target */
  padding: 0;
  background: transparent;
  border: 3px solid var(--on-ink);
  border-radius: var(--radius);
  color: var(--on-ink);
  cursor: pointer;
}
.nav-toggle:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
/* One button, two icons: whichever matches the current state is the one shown. */
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open  { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .site-header .wrap { gap: 12px; }

  /* Opened, the nav becomes a full-width panel under the header bar rather than a
     cramped dropdown. `display` is what artsy toggles, so .is-open has to win on both
     the property and the specificity. */
  .site-header .nav.is-open {
    display: flex;
    flex-direction: column;
    gap: 0;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: var(--ink);
    border-top: 3px solid var(--primary);
    padding: 4px 0 10px;
    z-index: 60;
    box-shadow: 0 10px 0 0 rgba(18, 18, 18, 0.25);
  }
  .site-header .nav.is-open a {
    padding: 15px 22px;
    border-bottom: none;
    border-left: 5px solid transparent;
  }
  .site-header .nav.is-open a:hover,
  .site-header .nav.is-open a:focus-visible { border-left-color: var(--primary); }
}

/* ---------- DISPLAY WEBFONT ----------
   This design is carried by its display type, but --font-display was a system stack, so
   headings rendered SF Pro on macOS, Segoe UI on Windows and Roboto on Android: three
   different brand impressions depending on the visitor's device, with different headline
   widths and line breaks. One self-hosted face fixes that and keeps third-party hosts at
   zero, which is why this is not loaded from a font CDN.

   Latin subset only (18KB). It already covers the Spanish accented characters, which live
   in U+0000-00FF, so the ES build needs no second file.

   Declared across 400-900 on purpose: Archivo Black ships ONE weight, and the design asks
   for font-weight 900 everywhere. Without the range the browser would synthesise a faux
   bold on top of an already-black face, which smears the letterforms. */
@font-face {
  font-family: "Archivo Black";
  src: url("/assets/fonts/archivo-black-latin.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;   /* render in the fallback immediately, swap when the file lands */
}

:root {
  --font-display: "Archivo Black", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
                  Roboto, "Helvetica Neue", Arial, sans-serif;
  /* artsy.css sets --font-body: var(--font-display). Left alone, overriding the display
     face would drag every paragraph into a display weight too, which is unreadable at body
     size. Body stays on the system stack: fast, familiar, and zero extra requests. */
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
}

/* Source line under the city housing diagnosis. Quiet, but present: the figures are real and
   the page should say where they came from. */
.source-note {
  margin-top: 14px;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--ink-soft, #55605a);
}
