/* ==========================================================================
   The Bridal Journey — Porter standard single-post template
   Ported verbatim from reference/a-dress-of-her-own.html.
   Measured off a live Porter feature: 1400 band, 140 inset, 540 cols, 40 gutter.
   Do not "tidy" the percentages. They are the design.
   ========================================================================== */

/* ---------- self-hosted faces ---------- */
@font-face{
  font-family:"Libre Caslon Display";
  font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/libre-caslon-display-400.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Libre Caslon Text";
  font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/libre-caslon-text-400.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* The italic run in the H1 comes from here — Libre Caslon Display has no italic cut. */
@font-face{
  font-family:"Libre Caslon Text";
  font-style:italic; font-weight:400; font-display:swap;
  src:url("fonts/libre-caslon-text-400italic.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Inter";
  font-style:normal; font-weight:100 900; font-display:swap;
  src:url("fonts/inter-var.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ---------- tokens (shared by the article and the homepage) ---------- */
.tbj-article,.tbj-home,.tbj-site{
  --paper:#ffffff;
  --ink:#14110d;
  --ink-soft:#6a6259;
  --ink-faint:#9c948a;
  --rule:#ddd7cf;
  --fpo:#efece7;
  --fpo-ink:#a49a8d;
  --fpo-ink2:#8a7f70;

  --display:"Libre Caslon Display",Georgia,"Times New Roman",serif;
  --body:"Libre Caslon Text",Georgia,"Times New Roman",serif;
  --util:"Inter",-apple-system,"Helvetica Neue",Arial,sans-serif;

  /* Porter's article grid, measured: 1400 band, 140 inset, 540 columns, 40 gutter */
  --band:min(94vw,1400px);
  --inset:10%;
  --col:38.571%;
  --gutter:2.857%;
  --textcol:51.428%;
  --herow:88.571%;
}

/* ---------- local reset (Oxygen ships no normalize we can rely on) ---------- */
.tbj-article *{box-sizing:border-box}
.tbj-article{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:16px;
  line-height:1.625;
  -webkit-font-smoothing:antialiased;
}
.tbj-article img{display:block;max-width:100%;height:auto}
.tbj-article p{margin:0}

.tbj-article .band{width:var(--band);margin-inline:auto;position:relative}

/* two-track body grid: [inset] [image col] [gutter] [text col] [inset] */
.tbj-article .grid{
  display:grid;
  grid-template-columns:var(--inset) var(--col) var(--gutter) var(--col) var(--inset);
}
/* Porter holds the image column in place while the text scrolls past it —
   verified on a live feature: position:sticky, top:20px, on the 560px image
   column. align-self:start is the load-bearing half: a grid item defaults to
   stretch, which fills the row and leaves sticky nothing to travel within. */
.tbj-article .g-img{grid-column:2;align-self:start;position:sticky;top:20px}
.tbj-article .g-text{grid-column:4}
.tbj-article .g-text-only{grid-column:4}

/* ---------- utility type ---------- */
.tbj-article .kicker{
  font-family:var(--util);font-weight:400;font-size:.75rem;letter-spacing:.25em;
  text-transform:uppercase;color:var(--ink);text-align:center;margin:0;
}
.tbj-article .caption{
  font-family:var(--util);font-weight:300;font-size:.75rem;line-height:1.5;
  letter-spacing:.042em;color:var(--ink-soft);margin:14px 0 0;max-width:44ch;
}

/* ---------- article head ---------- */
.tbj-article .head{padding:clamp(2rem,4vh,2.5rem) 0 0}
.tbj-article h1{
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(2.125rem,3.85vw,3.75rem);
  line-height:1;
  text-transform:uppercase;
  margin:2.6rem 0 0;
  margin-left:var(--inset);
  max-width:64%;
  text-wrap:balance;
}
.tbj-article h1 em{font-family:var(--body);font-style:italic}

.tbj-article .rail{
  position:absolute;
  right:0;
  top:3.2rem;
  width:50px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:2.6rem;
}
.tbj-article .rail .vlabel{
  writing-mode:vertical-rl;
  font-family:var(--util);font-weight:300;font-size:.625rem;
  letter-spacing:.3em;text-transform:uppercase;color:var(--ink-faint);margin:0;
}
.tbj-article .rail .date{
  font-family:var(--display);font-size:1.875rem;line-height:1.25;text-align:center;margin:0;
}
.tbj-article .rail .date span{
  display:block;font-family:var(--util);font-weight:300;font-size:.625rem;
  line-height:1.25;letter-spacing:.05em;color:var(--ink-faint);
}

.tbj-article .hero{width:var(--herow);margin-top:3.9rem}
.tbj-article .standfirst{
  margin:4.5rem 0 0;
  margin-left:13.43%;
  width:51.7%;
  font-family:var(--display);
  font-size:clamp(1.15rem,1.55vw,1.5rem);
  line-height:1.5;
}
/* Byline and photo credit sit below the standfirst as their own group, not
   inline inside it — inline the byline wrapped and orphaned the word "By". */
.tbj-article .head-credits{margin:1.4rem 0 0;margin-left:13.43%}
.tbj-article .byline,
.tbj-article .photocredit{
  font-family:var(--util);font-weight:300;font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;margin:0;
}
.tbj-article .byline{color:var(--ink)}
.tbj-article .photocredit{color:var(--ink-soft);letter-spacing:.042em;margin-top:.55rem}
/* keep "By" and the name together on one line */
.tbj-article .byline .author,
.tbj-article .photocredit .author{white-space:nowrap}
.tbj-article .photocredit a{color:inherit;text-decoration:none}
.tbj-article .photocredit a:hover{text-decoration:underline;text-underline-offset:.2em}

/* ---------- plates (image slots) ---------- */
.tbj-article figure{margin:0}
.tbj-article .plate{
  background:var(--fpo);display:flex;align-items:center;justify-content:center;
  padding:1.5rem;text-align:center;
}
.tbj-article .plate span{
  font-family:var(--util);font-weight:400;font-size:.625rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--fpo-ink);line-height:1.9;
}
.tbj-article .plate span b{display:block;font-weight:600;color:var(--fpo-ink2)}
.tbj-article .r32{aspect-ratio:3/2}
.tbj-article .r34{aspect-ratio:3/4}
.tbj-article .r45{aspect-ratio:4/5}
.tbj-article .r23{aspect-ratio:2/3}
.tbj-article .plate img{width:100%;height:100%;object-fit:cover;display:block}
/* a filled plate drops the placeholder chrome */
/* A filled plate drops the placeholder chrome. The dominant colour arrives as
   an inline background-color and the 24px preview as --lqip, both from cached
   attachment meta — so a lazy slot shows a soft colour wash, never blank white. */
.tbj-article .plate.shot{padding:0;position:relative;overflow:hidden}
.tbj-article .plate.shot::before{
  content:"";position:absolute;inset:0;z-index:0;
  background-image:var(--lqip);background-size:cover;background-position:center;
  /* no filter: a 24px source upscaled to 540-1240px is already soft, and a
     live blur on ten large elements cost 1.6s of main-thread rasterisation. */
}
.tbj-article .plate.shot img{position:relative;z-index:1}

/* Fade-in runs only when JS is present; no JS, no opacity:0, images just show. */
.js .tbj-article .plate.shot img{opacity:0;transition:opacity .4s ease}
.js .tbj-article .plate.shot img.is-loaded{opacity:1}
@media (prefers-reduced-motion:reduce){
  .js .tbj-article .plate.shot img{transition:none}
}

/* hero-scale plates: 1240 of the 1400 band, flush to the band's left edge */
.tbj-article .wide{width:var(--herow)}

.tbj-article .movement{padding:clamp(3rem,6vh,6rem) 0 0}
.tbj-article .offset{margin-top:80px}

/* ---------- section subheads ----------
   Quiet markers, not display headings: same register as the Credits h2
   (util face, 11px, .24em, uppercase) with the same hairline rule used
   above the pull quotes, so the two devices read as one system. */
.tbj-article .sub{
  font-family:var(--util);font-weight:400;font-size:.6875rem;
  letter-spacing:.24em;text-transform:uppercase;color:var(--ink);
  position:relative;margin:clamp(2.75rem,6vh,4rem) 0 1.5rem;padding-top:1.5rem;
}
.tbj-article .sub::before{
  content:"";position:absolute;top:0;left:0;
  width:3rem;height:1px;background:currentColor;opacity:.4;
}
/* the first subhead opens the column — no leading gap needed */
.tbj-article .prose > .sub:first-child{margin-top:0}

/* ---------- body copy ---------- */
.tbj-article .prose p{margin:0 0 1.625em}
.tbj-article .prose p:last-child{margin-bottom:0}
.tbj-article .prose em,.tbj-article .prose i{font-style:italic}
.tbj-article .dropcap::first-letter{
  font-family:var(--display);float:left;font-size:3.9em;line-height:.8;
  padding:.05em .08em 0 0;
}

/* ---------- pull quote ---------- */
.tbj-article .pq{margin:clamp(4rem,9vh,7rem) 0;margin-left:var(--textcol);width:44.285%}
/* Hairline rule above the quote instead of an underline. An underline on
   non-interactive display type reads as a link; this keeps the Porter beat
   without implying anything is clickable. */
.tbj-article .pq{position:relative;padding-top:2.25rem;cursor:default}
.tbj-article .pq::before{
  content:"";position:absolute;top:0;left:0;
  width:3rem;height:1px;background:currentColor;opacity:.4;
}
.tbj-article .pq p{
  font-family:var(--display);
  font-size:clamp(1.6rem,2.5vw,2.5rem);
  line-height:1.25;margin:0;
  text-decoration:none;
}
.tbj-article .pq p em{font-style:normal;text-transform:uppercase}

/* ---------- shop the look ---------- */
.tbj-article .shop{margin:clamp(2.5rem,5vh,4rem) 0 0;margin-left:var(--textcol);width:var(--col)}
/* When the module sits inside the text column of a grid row — so the image
   beside it has something to stay with — the column already places it.
   It then runs on past the text measure to the band's right edge: 680 of the
   1400 band rather than 540, which buys the swatches ~28%. The left edge still
   starts on the text column, which is the rule that matters (§4). */
.tbj-article .g-text .shop{margin-left:0;width:125.926%}   /* 48.571% of band / 38.571% */
/* A pull quote nested in the column keeps the exact width it has everywhere
   else on the page — 44.285% of the band — so all three read as one device. */
.tbj-article .g-text .pq{margin-left:0;width:114.815%}    /* 44.285% of band / 38.571% */
/* copy that follows a module inside the column needs its own beat of air */
.tbj-article .g-text .shop + .prose{margin-top:clamp(2.75rem,7vh,4.5rem)}
/* opening copy in a column that then runs into a plate: the plate's own 80px
   offset supplies the gap, so only reset the prose's trailing margin */
.tbj-article .g-text > .prose:first-child > p:last-child{margin-bottom:0}
.tbj-article .shop-head{
  font-family:var(--util);font-weight:400;font-size:.6875rem;letter-spacing:.22em;
  text-transform:uppercase;padding-bottom:.5rem;border-bottom:1px solid var(--ink);
  display:inline-block;margin:0 0 1.9rem;
}
.tbj-article .goods{display:grid;grid-template-columns:repeat(2,1fr);column-gap:40px;row-gap:2.2rem}
.tbj-article .good a{color:inherit;text-decoration:none;display:block}
.tbj-article .good .swatch{
  background:var(--fpo);aspect-ratio:3/4;display:flex;align-items:center;
  justify-content:center;margin-bottom:.9rem;overflow:hidden;
}
.tbj-article .good .swatch span{
  font-family:var(--util);font-size:.5625rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--fpo-ink);
}
.tbj-article .good b{
  display:block;font-family:var(--util);font-weight:600;font-size:.6875rem;
  letter-spacing:.09em;text-transform:uppercase;text-align:center;
}
.tbj-article .good i{
  display:block;font-style:normal;font-family:var(--body);font-size:.8125rem;
  line-height:1.45;color:var(--ink-soft);text-align:center;margin-top:.25rem;
}
.tbj-article .good a:hover b{text-decoration:underline;text-underline-offset:.2em}
.tbj-article .good a:focus-visible{outline:1px solid var(--ink);outline-offset:4px}

/* ---------- credits ---------- */
.tbj-article .credits{
  margin:clamp(4rem,9vh,7rem) var(--inset) 0;
  padding-top:clamp(3rem,7vh,6rem);
  border-top:1px solid var(--rule);
}
.tbj-article .credits h2{
  font-family:var(--util);font-weight:400;font-size:.6875rem;letter-spacing:.24em;
  text-transform:uppercase;margin:0 0 2.6rem;
}
.tbj-article .credits dl{
  margin:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  column-gap:40px;row-gap:1.6rem;
}
.tbj-article .credits dt{
  font-family:var(--util);font-weight:300;font-size:.625rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:.25rem;
}
.tbj-article .credits dd{margin:0;font-size:.9375rem;line-height:1.5}
.tbj-article .credits dd a{
  color:var(--ink);text-decoration:underline;text-underline-offset:.18em;
  text-decoration-color:var(--rule);
}
.tbj-article .credits dd a:hover{text-decoration-color:var(--ink)}

/* ---------- mobile: single column, offsets collapse, no sideways scroll ---------- */
@media (max-width:900px){
  .tbj-article{--band:88vw}
  .tbj-article .grid{grid-template-columns:1fr}
  .tbj-article .g-img,.tbj-article .g-text,.tbj-article .g-text-only{grid-column:1}
  /* single column: nothing to scroll past, so release it */
  .tbj-article .g-img{position:static;align-self:auto}
  .tbj-article h1{margin-left:0;max-width:none;margin-top:1.6rem}
  .tbj-article .rail{
    position:static;flex-direction:row;width:auto;gap:1.25rem;
    align-items:center;margin-top:1.5rem;
  }
  .tbj-article .rail .vlabel{writing-mode:horizontal-tb}
  .tbj-article .rail .date{font-size:1.1rem}
  .tbj-article .rail .date span{display:inline;margin-left:.4rem}
  /* The comp set hero-scale figures with an inline width, which its own mobile
     block could not override. §7 asks for everything full width here. */
  .tbj-article .hero,.tbj-article .wide{width:100%}
  .tbj-article .standfirst,.tbj-article .photocredit{margin-left:0;width:100%}
  .tbj-article .pq,.tbj-article .shop{margin-left:0;width:100%}
  .tbj-article .g-text .shop,.tbj-article .g-text .pq{width:100%}
  .tbj-article .offset{margin-top:1.5rem}
  .tbj-article .goods{grid-template-columns:repeat(2,1fr);column-gap:1.25rem}
  .tbj-article .credits{margin-inline:0}
}
@media (prefers-reduced-motion:reduce){
  .tbj-article *{animation:none!important;transition:none!important}
}

/* ==========================================================================
   Shared site chrome. Porter carries the same masthead on the homepage and on
   every feature — verified on a live article — so it lives here, not in home.css.
   ========================================================================== */
.tbj-site{--site-band:min(94vw,1400px);background:var(--paper);color:var(--ink)}
.tbj-site .site-band{width:var(--site-band);margin-inline:auto}
.tbj-site a{color:inherit;text-decoration:none}
.tbj-site p{margin:0}

/* ---------- site masthead (shared: homepage + feature) ---------- */
.tbj-site .site-head{padding:clamp(2rem,5vh,3.25rem) 0 clamp(1.75rem,4vh,2.75rem);text-align:center}
.tbj-site .tagline{
  /* Chronicle Display has an italic; Libre Caslon Display does not, so the
     italic comes from the Text cut — the same pairing as the article H1. */
  font-family:var(--body);font-style:italic;font-size:.875rem;line-height:1.25;
  color:var(--ink);margin:0 0 .85rem;
}
.tbj-site .wordmark{
  display:block;font-family:var(--display);font-weight:400;
  font-size:clamp(2rem,4.2vw,3.25rem);line-height:1;letter-spacing:.055em;
  text-transform:uppercase;margin:0;
}
.tbj-site .sections{
  display:flex;justify-content:center;flex-wrap:wrap;
  gap:clamp(1.1rem,2.6vw,2.6rem);margin-top:clamp(1.5rem,3.5vh,2.4rem);
}
.tbj-site .sections a,
.tbj-site .sections .section-off{
  font-family:var(--util);font-weight:400;font-size:.75rem;letter-spacing:.18em;
  text-transform:uppercase;padding-bottom:2px;
}
.tbj-site .sections a:hover,
.tbj-site .sections a[aria-current]{box-shadow:inset 0 -1px 0 var(--ink)}
/* sections with no archive yet: present as editorial frame, but not offered
   as something to click — muted, no pointer, not focusable */
.tbj-site .sections .section-off{color:var(--ink-soft);cursor:default}

/* ---------- site footer (shared) ----------
   Porter's own footer is the NET-A-PORTER retail footer — customer care,
   payments, app QR — none of which belongs on an editorial title. This is the
   editorial equivalent: mark, sections, credit, copyright. Nothing decorative,
   and no sign-up form standing in for functionality that does not exist. */
.tbj-site .site-foot{
  margin-top:clamp(4rem,10vh,8rem);padding:clamp(2.75rem,6vh,4rem) 0 clamp(3rem,7vh,4.5rem);
  border-top:1px solid var(--rule);text-align:center;
}
.tbj-site .site-foot .foot-mark{
  display:block;font-family:var(--display);font-weight:400;
  font-size:clamp(1.125rem,1.8vw,1.5rem);line-height:1;letter-spacing:.14em;
  text-transform:uppercase;margin-bottom:1.6rem;
}
.tbj-site .site-foot .sections{margin-top:0;margin-bottom:2rem}
.tbj-site .site-foot .foot-note{
  font-family:var(--body);font-size:.875rem;line-height:1.6;color:var(--ink-soft);
  max-width:46ch;margin:0 auto 1.9rem;
}
.tbj-site .site-foot .foot-legal{
  font-family:var(--util);font-weight:300;font-size:.6875rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-faint);
}
.tbj-site .site-foot .foot-legal a{border-bottom:1px solid var(--rule)}
.tbj-site .site-foot .foot-legal a:hover{border-bottom-color:var(--ink)}


@media (max-width:900px){
  .tbj-site{--site-band:88vw}
}

/* ==========================================================================
   Section archive. A row-per-feature list rather than a card grid, so it reads
   correctly with one feature as well as twenty.
   ========================================================================== */
.tbj-archive{background:var(--paper);color:var(--ink);font-family:var(--body)}
.tbj-archive .band{width:var(--site-band);margin-inline:auto}
.tbj-archive a{color:inherit;text-decoration:none}
.tbj-archive p{margin:0}
.tbj-archive img{display:block;max-width:100%;height:auto}

.tbj-archive .arch-head{
  text-align:center;padding:clamp(1rem,3vh,2rem) 0 clamp(2.5rem,6vh,4rem);
  border-bottom:1px solid var(--rule);margin-bottom:clamp(2.5rem,6vh,4.5rem);
}
.tbj-archive .arch-h{
  font-family:var(--display);font-weight:400;font-size:clamp(1.75rem,3.2vw,2.75rem);
  line-height:1.1;text-transform:uppercase;letter-spacing:.02em;margin:0 0 .8rem;
}
.tbj-archive .arch-count{
  font-family:var(--util);font-weight:300;font-size:.6875rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-faint);
}

.tbj-archive .feat{
  display:grid;grid-template-columns:58% 1fr;column-gap:4%;align-items:center;
  margin-bottom:clamp(3rem,8vh,6rem);
}
.tbj-archive .feat figure{margin:0;aspect-ratio:3/2;overflow:hidden}
.tbj-archive .feat img{width:100%;height:100%;object-fit:cover}
.tbj-archive .feat-kicker{
  font-family:var(--util);font-weight:400;font-size:.75rem;letter-spacing:.25em;
  text-transform:uppercase;margin:0 0 1.2rem;
}
.tbj-archive .feat-h{
  font-family:var(--display);font-weight:400;font-size:clamp(1.375rem,2.1vw,1.75rem);
  line-height:1.25;margin:0 0 1.2rem;
}
.tbj-archive .feat-h em{font-family:var(--body);font-style:italic}
.tbj-archive .feat-sf{
  font-family:var(--body);font-style:italic;font-size:1rem;line-height:1.625;
  color:var(--ink-soft);margin:0 0 1.8rem;
}
.tbj-archive .feat a.readlink{
  display:inline-block;font-family:var(--util);font-weight:300;font-size:.75rem;
  letter-spacing:.083em;border-bottom:1px solid var(--ink);padding-bottom:3px;
}
.tbj-archive .feat-date{
  font-family:var(--util);font-weight:300;font-size:.75rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-faint);margin-top:1.6rem;
}

@media (max-width:900px){
  .tbj-archive .feat{grid-template-columns:1fr;row-gap:1.5rem}
}
