/* ===========================================================================
   article.css — the ORIGINAL blog article layout.

   Loaded after blog.css and site.css, and it deliberately owns the whole
   article page, because the earlier template was a redesign: a dark full-bleed
   hero, an "In this article" contents box, a large grey Key Takeaway panel, a
   staggered photo mosaic and a "See it working on your floor" band. None of
   those are on the original page. The reference screenshots are the source of
   truth here.

   Shape:
      centred container
        article column ~72%, white, one hairline border
        sidebar     ~24%
      Recent Posts, three cards, BELOW the container

   Type comes from the brand book: Wix Madefor Display for headings at 800 with
   tight tracking, Wix Madefor Text for body, Space Mono for the small tracked
   eyebrow labels. No ad-hoc font stacks below.
   ========================================================================= */

.artpage {
  --artmain: 72%;
  --artside: 24%;
  display: grid;
  grid-template-columns: minmax(0, var(--artmain)) minmax(0, var(--artside));
  gap: clamp(1.5rem, 2.5vw, 2.5rem);
  align-items: start;
  width: min(78rem, calc(100vw - 2 * var(--gutter)));
  margin: clamp(1.5rem, 3vw, 2.5rem) auto clamp(2rem, 4vw, 3rem);
}

@media (max-width: 1000px) {
  .artpage { grid-template-columns: 1fr; }
}

.artmain {
  /* Live has NO card here: the article sits directly on the page. Ours drew a
     white panel with a border, which parity reported as a background
     difference on the title and on every paragraph of every article. */
  background: none;
  border: 0;
  border-radius: 0;
  padding: clamp(1.5rem, 3vw, 2.75rem) clamp(1.25rem, 3vw, 3rem)
           clamp(2rem, 3.5vw, 3rem);
  min-width: 0;
}

/* ---- header: byline, title, updated ------------------------------------- */
.arthead { margin: 0 0 1.4rem; }

.artby {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin: 0 0 1rem;
  font-family: var(--font-text);
  font-size: .82rem;
  color: var(--ink-2);
}
.artby__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: contain;
  background: var(--surface);
  padding: 3px;
  flex: none;
}
.artby__sep { color: var(--ink-3); }

.arttitle {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.6rem, 2.6vw, 2.15rem);
  line-height: 1.18;
  letter-spacing: -.015em;
  color: var(--ink);
  margin: 0 0 .7rem;
  max-width: 32ch;
}

.artupdated {
  font-family: var(--font-text);
  font-size: .82rem;
  color: var(--ink-2);
  margin: 0;
}

/* ---- body --------------------------------------------------------------- */
.artbody {
  font-family: var(--font-text);
  font-size: 1rem;
  line-height: 1.62;
  color: var(--ink-2);
}
.artbody > p { margin: 0 0 1rem; max-width: none; }
.artbody > p:last-child { margin-bottom: 0; }
.artbody strong, .artbody b { color: var(--ink); font-weight: 700; }
.artbody a { color: var(--red-deep); }

/* The lead is the first paragraph. In the original it is the same size as the
   rest -- there is no oversized standfirst. */
.artbody > .artlead { font-size: 1rem; line-height: 1.62; color: var(--ink-2); }

.artbody > h2, .artbody > h3 {
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--ink);
  letter-spacing: -.01em;
  line-height: 1.22;
  margin: 1.8rem 0 .7rem;
}
.artbody > h2 { font-size: 1.32rem; }
.artbody > h3 { font-size: 1.12rem; }

.artbody > ul, .artbody > ol { margin: 0 0 1rem; padding-left: 1.15rem; }
.artbody > ul li, .artbody > ol li { margin: 0 0 .4rem; }

/* The customer's logo at the top of a case study. Small, left, above the copy
   -- not a full-width feature graphic. */
.artlogo { margin: 0 0 1.1rem; }
.artlogo img {
  display: block;
  width: auto;
  max-width: 12rem;
  max-height: 2.75rem;
  height: auto;
}

/* Key Takeaway. A short note before the article, not a large panel. */
.artnote {
  border-left: 3px solid var(--red);
  background: none;
  padding: .1rem 0 .1rem 1rem;
  margin: 0 0 1.3rem;
}
.artnote__label {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 .3rem;
}
.artnote__body p { margin: 0; font-size: .95rem; line-height: 1.55; color: var(--ink); }

.artquote {
  margin: 1.2rem 0;
  padding-left: 1rem;
  border-left: 3px solid var(--red);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.4;
  color: var(--ink);
}

/* ---- images -------------------------------------------------------------- */
.artfig { margin: 1.2rem 0; }
/* NOT stretched to the column. MEASURED across six articles on 2026-08-25:
   live's body images run 176px to 269px wide, and only a genuine feature photo
   reaches 740px. `width: 100%` blew every one of them up to the full 802px
   column, which is why our articles measured 1.45x to 3.07x live's height.
   `width: auto` with a cap lets a small photo stay small and a large one fill
   the measure, which is what live does. */
.artfig img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
}
/* Centred under the picture. The figure is the width of the image, so
   text-align centres the caption ON the image, not on the text column. */
.artfig figcaption, .artstrip figcaption {
  font-size: .8rem; color: var(--ink-3); margin-top: .45rem; text-align: center;
}

/* A run of photos is ONE flat strip at a single height, hairline gaps. The
   original reads them as a single gallery band. */
.artstrip {
  /* MEASURED on live: three SQUARE photos at 243x243 with a hairline gap,
     read as one gallery band. */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  margin: 1.3rem 0;
}
/* The strip is a grid of live's OWN sizes now (blog_image_sizes.py stamps an
   inline width on each image from the live page), so the cell must not stretch
   or crop them. `object-fit: cover` on a forced 1:1 box also broke the standing
   rule against forcing an image into a shape it does not have. */
.artstrip img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
}
@media (max-width: 640px) {
  .artstrip { grid-template-columns: 1fr; }
}

.artrule { border: 0; border-top: 1px solid var(--line); margin: 1.9rem 0 1.6rem; }

/* ---- compact meeting CTA -------------------------------------------------
   Small image left, copy right, on the white page. No dark panel, no hero. */
.mcta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(1rem, 2vw, 1.75rem);
  align-items: center;
  background: none;
  padding: 0;
  margin: 1.8rem 0;
}
.mcta__media { width: 160px; flex: none; }
.mcta__media img {
  display: block;
  width: 160px;
  height: 178px;
  object-fit: cover;
  object-position: center top;
}
.mcta__eyebrow {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .78rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 .45rem;
}
.mcta__head {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.15rem, 2vw, 1.55rem);
  line-height: 1.15;
  letter-spacing: -.015em;
  color: var(--ink);
  margin: 0 0 .9rem;
}
.mcta__btn { padding: .7rem 1.4rem; font-size: .9rem; }
@media (max-width: 560px) {
  .mcta { grid-template-columns: 1fr; }
  .mcta__media, .mcta__media img { width: 140px; height: auto; }
}

/* ---- FAQ ---------------------------------------------------------------- */
.artfaq { margin: 2rem 0 0; }
.artfaq__head {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.32rem;
  color: var(--ink);
  margin: 0 0 .8rem;
}
.artfaq__item { border-bottom: 1px solid var(--line-soft); }
.artfaq__q {
  font-family: var(--font-text);
  font-weight: 600;
  font-size: .98rem;
  color: var(--ink);
  padding: .8rem 0;
  cursor: pointer;
}
.artfaq__a p { font-size: .95rem; line-height: 1.6; color: var(--ink-2); margin: 0 0 .9rem; }

/* ---- inline e-book block -------------------------------------------------
   Small cover left; eyebrow, heading, rule, one line of copy and the stacked
   form on the right. */
/* TWO parts, not two columns. `.ebin__top` is the two-column row -- cover
   left, heading right. The form is a SIBLING of that row, so it runs the full
   width of the section underneath instead of being trapped in the right-hand
   column with a tall empty gap beside it. */
.ebin { margin: 0 0 1.4rem; }
.ebin__top {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
  margin: 0 0 1.6rem;
}
@media (max-width: 720px) { .ebin__top { grid-template-columns: 1fr; } }

.ebin__media img { display: block; width: 100%; max-width: 15rem; height: auto; }

.ebin__eyebrow {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .78rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--red);
  margin: 0 0 .45rem;
}
.ebin__head {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.3rem, 2.4vw, 1.75rem);
  line-height: 1.08;
  letter-spacing: -.02em;
  color: var(--ink);
  margin: 0 0 .7rem;
}
.ebin__rule { border: 0; border-top: 1px solid var(--line); margin: 0 0 .8rem; width: 55%; }
.ebin__intro {
  font-family: var(--font-text);
  font-size: .88rem;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0 0 1.1rem;
}

/* Fields stack full width: first and last name are NOT side by side in the
   original, and the form spans the section rather than half of it. */
.lgform--ebin { max-width: none; width: 100%; gap: .85rem; }
.lgform--ebin .lgfield__input { border-radius: var(--r-pill); }
.lgform__send--sm { padding: .6rem 1.5rem; font-size: .85rem; }

/* ---- chips, categories, share ------------------------------------------- */
/* 1.6rem on top left a visible hole under the Submit button, which already
   carries its own margin. */
.artchips { display: flex; flex-wrap: wrap; gap: .45rem; margin: .9rem 0 1rem; }

/* .artbody carries a 4rem bottom padding to hold prose off the chips. When the
   LAST thing in the body is the download block, that padding stacked on top of
   the block's own margin and left ~100px of white between the Submit button
   and the chips. Measured: 99.9px before, 36.8px after. */
.artbody:has(> .ebin:last-child) { padding-bottom: 0; }
.artchip {
  font-family: var(--font-text);
  font-size: .78rem;
  color: var(--ink-2);
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: .35rem .7rem;
}
.artchip:hover { color: var(--ink); border-color: var(--ink-3); }

.artcats { font-family: var(--font-text); font-size: .82rem; margin: 0 0 1.2rem; }
.artcats a { color: var(--ink-2); }
.artcats a:hover { color: var(--red-deep); }

.artshare {
  display: flex;
  gap: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  font-size: .95rem;
}

/* ---- Recent Posts, below the container ---------------------------------- */
.artrel {
  width: min(78rem, calc(100vw - 2 * var(--gutter)));
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
}
.artrel__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0 1.1rem;
}
.artrel__label {
  font-family: var(--font-text);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  margin: 0;
}
.artrel__all { font-family: var(--font-text); font-size: .85rem; color: var(--ink-2); }
.artrel .postgrid { padding: 0; }

/* ---- sidebar sits in the container now, not in a grid gutter ------------ */
.artpage .artaside {
  grid-column: auto;
  grid-row: auto;
  position: sticky;
  top: calc(var(--header-h) + 1rem);
  width: 100%;
  margin: 0;
}
@media (max-width: 1000px) {
  .artpage .artaside { position: static; margin-top: 2rem; }
}

/* A sub-heading below h2. Wix has no element at this level and writes them as
   blockquotes, so blog_article.py promotes the short ones (see SUBHEAD_MAX).
   Without this they rendered as pull quotes on a red rule mid-list. */
.arth3 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.06rem;
  line-height: 1.3;
  color: var(--ink);
  margin: 1.6rem 0 .5rem;
}

/* ---- Recent Posts strip: live's scale, not the blog index's ---------------
   The same .postcard component is used on /blog, where live sets a large card
   title, and at the foot of an article, where live sets 14px on a card with no
   fill and no corner. MEASURED across six articles: 14px vs our 21.4px, and
   transparent vs our white with a 10px corner. Scoped to .artrel so the blog
   index keeps its own, correct, larger treatment. */
.artrel .postcard {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.artrel .postcard__title { font-size: .875rem; line-height: 1.35; }
.artrel .postcard__title a { font-size: inherit; }
.artrel .postcard__excerpt { font-size: .8125rem; }

/* live sets the caption at 16px in the body ink, not 12.8px grey */
.artfig figcaption, .artstrip figcaption { font-size: 1rem; color: var(--ink); }

/* ---- opening photo beside the opening copy ------------------------------ */
/* Live opens an article that has no customer logo with the picture on the
   left, about 150px wide, and the first paragraph beside it. Only a case
   study's customer logo goes through .artlogo, which caps height at 2.75rem;
   sending a photograph through it squashed an 800x800 unit shot to 44px. */
.artintro {
  display: grid; grid-template-columns: minmax(0, 170px) 1fr;
  gap: clamp(1.25rem, 2.5vw, 2rem); align-items: start;
  margin: 0 0 1.6rem;
}
.artintro__media { margin: 0; }
.artintro__media img { display: block; width: 100%; height: auto; border-radius: 6px; }
.artintro__copy > .artlead { margin-top: 0; }
@media (max-width: 620px) {
  .artintro { grid-template-columns: 1fr; }
  .artintro__media { max-width: 170px; }
}

/* ==========================================================================
   Matched to live, measured across all 30 articles on 2026-08-25
   ========================================================================== */

/* Section headings are PURE BLACK at 25px on live, not ink at 21.1px.
   119 atoms across the 30 articles reported one or both. */
/* h2 ONLY. Setting h3 and .arth3 black too was an overcorrection: live keeps
   those at ink rgb(45,39,39), and 6 atoms flipped to reporting the difference
   the other way round. */
.artbody > h2 { color: #000; font-size: 1.5625rem; }

/* Live rounds NO image in an article: 172 atoms reported a 10px corner on ours
   against 0 on live, across the body figures, the sidebar thumbnails and the
   related-post cards. */
.artbody img,
.artfig img,
.artstrip img,
.artaside__pthumb img,
.artrel .postcard img { border-radius: 0; }

/* Body links are UI Red on live, not --red-deep. */
.artbody a { color: var(--red-ui, #ff3a42); }


/* ---- long URLs must be allowed to break, added 2026-08-25 ---------------
   Two posts end with a "Sources:" bullet holding a bare web address. A URL is
   one unbreakable word, so on a 390px screen the list item demanded 941px and
   the browser widened the whole page to fit it:
   /post/understanding-proximity-detection-technology-for-pedestrian-detection-
   in-warehouses wanted 999px, and /post/safety-technology-to-meet-osha-
   requirements 868px.

   The value is "anywhere" and not "break-word" on purpose: only "anywhere"
   reduces the element's MIN-CONTENT width, which is what lets the parent
   shrink. With "break-word" the text wraps but the page stays wide. Ordinary
   prose is unaffected either way, since a break is used only when a word
   cannot fit. */
.artbody, .artbody p, .artbody li, .artbody a, .artbody figcaption {
  overflow-wrap: anywhere;
}

/* ==========================================================================
   PRE-2024 CASE STUDIES: the editorial layout of the reference
   User, 2026-08-27, with a screenshot of the GFS page. These four articles are
   older and are laid out as an editorial piece, not as a modern post: pairs of
   picture-and-text side by side, one row of benefit photos, thin grey rules,
   and a bordered article column. site/post/<slug>/index.html carries the
   wrappers; tools/old_case_study.py writes them.
   ========================================================================== */

/* the article column sits in a thin dark frame, as on the reference */
.artpage .artmain {
  border: 1px solid var(--ink, #101114);
  border-radius: 2px;
  background: #fff;
}
.artpage .artmain > .artbody,
.artpage .artmain > .arthead { padding-inline: clamp(1.25rem, 3vw, 2.75rem); }

/* 1. company intro: logo left, underlined heading and italic description right */
.csintro {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
  margin-block: clamp(1.25rem, 3vw, 2rem);
}
.csintro__logo p, .csintro__logo { margin: 0; }
.csintro__logo img { width: 100%; height: auto; display: block; }
.csintro__copy > h2 {
  margin: 0 0 .6rem;
  font-style: italic;
  text-decoration: underline;
  text-underline-offset: .18em;
}
.csintro__copy > .artlead { font-style: italic; margin: 0; }

/* 2. product block: photo left, its paragraph right */
.csprod {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
  margin-block: clamp(1.5rem, 3vw, 2.25rem);
}
.csprod__shot figure, .csprod__shot { margin: 0; }
.csprod__shot img { width: 100%; height: auto; display: block; }
.csprod__copy p { margin: 0; }

/* 3. the benefit photos: one row, equal height, very small gaps */
.csrow {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-block: clamp(1.25rem, 3vw, 2rem);
}
.csrow figure { margin: 0; }
.csrow img {
  width: 100% !important;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.csrow figcaption { display: none; }   /* the reference shows no captions here */

/* 4. thin grey dividers, not the red accent rule */
hr.csrule {
  border: 0;
  border-top: 1px solid var(--line, #e3e4e7);
  margin-block: clamp(1.75rem, 4vw, 2.75rem);
}

/* the takeaway: red hairline on the left, large bold centred text, no card */
.artpage .artmain .artquote {
  border-left: 3px solid var(--red, #ff3a42);
  background: none;
  padding: .25rem 0 .25rem clamp(1rem, 3vw, 2rem);
  margin-block: clamp(2rem, 5vw, 3.25rem);
  text-align: center;
  font-weight: 700;
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  line-height: 1.45;
}

@media (max-width: 760px) {
  .csintro, .csprod { grid-template-columns: minmax(0, 1fr); }
  .csrow { grid-template-columns: minmax(0, 1fr); gap: 10px; }
}

/* ---- pre-2024 case studies: corrections against the reference -----------
   User, 2026-08-27, comparing our GFS page with live's. */

/* the title is set in capitals sitewide; the reference keeps it title case */
.artmain .arttitle { text-transform: none; }

/* "Updated: <date>", small and quiet under the title, as on the reference */
.artmain .artupdated {
  margin: .5rem 0 0;
  font-size: .82rem;
  color: var(--ink-2, #4a4d55);
}

/* no red accent rule above these headings: the reference has a plain heading
   under a thin grey divider, nothing else */
.csintro__copy > .arth::before,
.artmain .artbody > .arth::before { content: none; }

/* the company heading is a normal heading, not an article-size one. At the
   article size it ran to three lines in a column this narrow. */
.csintro__copy > .arth {
  font-size: clamp(1.05rem, 1.35vw, 1.3rem);
  line-height: 1.3;
}

/* the italic description sits directly under it */
.csintro__copy > .artlead { font-size: .95rem; line-height: 1.6; }

/* the logo column no longer has a tall text column beside it, so the row
   aligns on its top edge and the intro closes tight to the paragraphs */
.csintro { align-items: start; margin-bottom: clamp(1rem, 2.5vw, 1.5rem); }
