/* The blog's own stylesheet. The blog reads as its own place, livelier than the
   main site, so it shares only the tokens and the typeface with styles.css.

   One layout, "Cinema": the lead photo fills the screen under a dark scrim,
   the short answer sits on a sand card. See website/README.md, "The blog's
   layout". */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/InterVariable-latin.woff2") format("woff2");
}

:root {
  --canvas: #f6f3ec;
  --surface: #fdfbf7;
  --surface-deep: #ece8de;
  --ink: #25251f;
  --ink-soft: #5c594f;
  --ink-body: #4f4d45;
  --moss: #465d49;
  --moss-dark: #354838;
  --clay: #b88c69;
  --clay-light: #e6c7a8;
  /* Clay dark enough for small text and focus rings on the canvas (4.7:1). */
  --clay-ink: #8a6446;
  --scrim: 20, 18, 14;
  --line: rgba(37, 37, 31, 0.12);
  --radius-sm: 0.75rem;
  --radius-md: 1.25rem;
  --radius-lg: 2rem;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  /* Breakout grid: a text column, a wider column for sliders, and the full bleed. */
  --text: 40rem;
  --wide-extra: 9rem;
  --gutter: max(1rem, env(safe-area-inset-left, 0px));
  --wide: min(100% - 2 * var(--gutter), var(--text) + 2 * var(--wide-extra));
  --column: min(100% - 2 * var(--gutter), var(--text));
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--canvas);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-optical-sizing: auto;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Inherited by every element: no orphaned last words, in headings or body text. */
  text-wrap: pretty;
}

img { display: block; max-width: 100%; }
a { color: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--clay-ink); outline-offset: 3px; }
[id] { scroll-margin-top: 2rem; }
/* Keyboard focus and anchor jumps stop below the masthead pinned to the top. */
html { scroll-padding-top: 4.5rem; }

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.65rem 0.9rem;
  border-radius: 0.5rem;
  color: #fff;
  background: var(--moss-dark);
  transform: translateY(-180%);
  transition: transform 160ms var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- reading bar ----------
   The only thing that stays on screen while reading. A visible track from the
   start, so it reads as a bar before it fills; below the status bar on a
   notched phone. Shown on articles only. */
.read-progress {
  position: fixed;
  z-index: 40;
  top: env(safe-area-inset-top, 0px);
  right: 0;
  left: 0;
  display: none;
  height: 6px;
  background: rgba(37, 37, 31, 0.12);
  pointer-events: none;
}
body:has(article.prose) .read-progress { display: block; }
.read-progress span {
  display: block;
  height: 100%;
  background: var(--clay);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
}

/* ---------- masthead ----------
   One centred pill, like a magazine masthead and unlike the main site's
   brand-left, links-right bar, so the blog reads as its own place. "Blog home"
   leads to all articles; the quieter RoomDecor credit leads to the main site.
   Pinned to the top of the screen, just under the reading bar, so the way out
   is always there while reading. */
.masthead {
  position: fixed;
  z-index: 45;
  inset: 0 0 auto;
  display: flex;
  justify-content: center;
  padding: calc(6px + 0.75rem + env(safe-area-inset-top, 0px)) var(--gutter) 0;
  pointer-events: none;
}
.masthead nav {
  pointer-events: auto;
  display: inline-flex;
  align-items: stretch;
  min-height: 2.9rem;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 999px;
  background: rgba(246, 243, 236, 0.76);
  box-shadow: 0 6px 24px rgba(37, 37, 31, 0.12);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .masthead nav { background: rgba(246, 243, 236, 0.96); }
}
/* Over the lead photo the pill steps back to white text on the photo; blog.js
   drops .is-over-photo once the photo has scrolled under it, and the frosted
   pill fades in. Scoped to .js: without script nothing would drop the class,
   and white text would vanish over the page below the photo. */
.masthead nav, .masthead-rule { transition: background-color 250ms ease, border-color 250ms ease, box-shadow 250ms ease; }
.js .masthead.is-over-photo nav { border-color: transparent; background: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.js .masthead.is-over-photo a, .js .masthead.is-over-photo a.masthead-maker { color: #fff; text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35); }
.js .masthead.is-over-photo .masthead-rule { background: rgba(255, 255, 255, 0.45); }
@media (prefers-reduced-motion: reduce) {
  .masthead nav, .masthead-rule, .masthead a { transition: none; }
}
.masthead a { display: inline-flex; align-items: center; color: var(--ink); text-decoration: none; transition: color 150ms ease; }
.masthead a:active { transform: scale(0.96); }
.masthead-title { padding: 0 0.95rem 0 1.3rem; font-size: 1.02rem; font-weight: 720; letter-spacing: -0.02em; }
.masthead-rule { width: 1px; margin-block: 0.75rem; background: var(--line); }
.masthead a.masthead-maker { gap: 0.45rem; padding: 0 1.15rem 0 0.9rem; color: var(--ink-soft); font-size: 0.86rem; font-weight: 560; }
.masthead a.masthead-maker:hover { color: var(--ink); }
/* The app's own icon, with the iOS corner radius (22.4% of the side). */
.brand-mark { flex: none; width: 1.6rem; height: 1.6rem; border-radius: 22.4%; background: var(--surface-deep) url("app-icon.webp") center / cover no-repeat; }

/* ---------- lead: photo and title ---------- */
.art-head { position: relative; height: max(34rem, 100svh); overflow: hidden; color: #fff; }
.art-head.is-index { height: max(28rem, 72svh); }
.art-photo { position: absolute; inset: 0; margin: 0; }
.art-photo img { width: 100%; height: 100%; object-fit: cover; }
.art-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(var(--scrim), 0.86) 0%, rgba(var(--scrim), 0.55) 34%, rgba(var(--scrim), 0) 62%),
    linear-gradient(to bottom, rgba(var(--scrim), 0.35), rgba(var(--scrim), 0) 22%);
}
.art-title { position: absolute; right: 0; bottom: calc(max(3rem, 7svh) + env(safe-area-inset-bottom, 0px)); left: 0; width: var(--wide); margin: 0 auto; }
.eyebrow { margin: 0 0 1rem; color: var(--clay-light); font-size: 0.76rem; font-weight: 760; letter-spacing: 0.12em; text-transform: uppercase; }
.art-title h1 { max-width: 14ch; margin: 0; font-size: clamp(2.7rem, 7.2vw, 6.2rem); font-weight: 650; letter-spacing: -0.035em; line-height: 1; }
.dek { max-width: 36rem; margin: 1.5rem 0 0; color: rgba(255, 255, 255, 0.85); font-size: clamp(1.08rem, 1.6vw, 1.3rem); line-height: 1.5; }
.byline { margin: 1.4rem 0 0; font-size: 0.86rem; opacity: 0.75; }

/* ---------- article body: breakout grid ---------- */
.prose { padding-block: clamp(3rem, 7vw, 5.5rem) 1rem; font-size: clamp(1.04rem, 1.2vw, 1.13rem); line-height: 1.75; }
.prose section {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, var(--wide-extra))
    [text-start] min(var(--text), 100% - 2 * var(--gutter)) [text-end]
    minmax(0, var(--wide-extra)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
}
.prose section > * { grid-column: text; }
.prose p, .prose ol, .prose ul { margin: 0 0 1.25em; color: var(--ink-body); }
/* Body text is justified; hyphenation (by the page's lang) keeps a narrow
   column from opening rivers between words. */
.prose p, .prose li { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }
.prose li + li { margin-top: 0.4em; }
.prose strong { color: var(--ink); }
.prose h2 { margin: clamp(2rem, 4vw, 3rem) 0 1.1rem; font-size: clamp(1.85rem, 3.6vw, 2.75rem); font-weight: 640; letter-spacing: -0.025em; line-height: 1.08; }
.prose h3 { margin: 2.2rem 0 0.5rem; font-size: 1.2rem; letter-spacing: -0.01em; }
/* One clay line, one left edge: the dash above the FAQ heading and the bar
   beside each caption sit on the text column's left edge. Only the FAQ gets the
   dash, marking where the article ends and the questions begin. */
.prose section[data-faq] > h2::before { content: ""; display: block; width: 2.5rem; height: 3px; margin-bottom: 1.2rem; border-radius: 2px; background: var(--clay); }

/* The short answer on a soft sand card, a shade warmer than the page. */
.prose section.summary { display: block; width: var(--wide); margin-inline: auto; padding: clamp(1.4rem, 3vw, 2.2rem); border-radius: var(--radius-md); background: #efe6d9; }
.summary h2 { margin: 0 0 0.6rem; color: var(--clay-ink); font-size: 0.8rem; font-weight: 760; letter-spacing: 0.12em; text-transform: uppercase; }
.summary p { margin: 0; color: var(--ink); font-size: clamp(1.08rem, 1.5vw, 1.22rem); line-height: 1.55; }

/* ---------- figures ----------
   A photo with no numbers or words in it runs edge to edge. A diagram (its
   labels and dimension lines are drawn at a lower resolution) and a slider keep
   the wide column. The caption repeats the statement the image illustrates, in
   the text column, with a clay bar beside it. */
.prose figure { margin: 2.5rem 0 3rem; }
.prose figure.figure-wide { grid-column: full; }
.prose .figure-wide img, .prose .figure-diagram img, .prose figure .image-draft { width: 100%; height: auto; object-fit: cover; background: var(--surface-deep); }
.prose .figure-wide img, .prose .figure-wide .image-draft { max-height: 88svh; }
.prose figure .image-draft { aspect-ratio: 3 / 2; }
/* A diagram keeps its own shape, 3:2 or wider (see tools/diagrams.py). */
.prose figure.figure-diagram { grid-column: wide; }
.prose .figure-diagram img, .prose .figure-diagram .image-draft { border-radius: var(--radius-sm); }
.prose figure.figure-slider { grid-column: wide; }
.prose figure.figure-slider.is-portrait { grid-column: text; justify-self: center; width: min(100%, 30rem); }
.prose figcaption { width: min(100%, var(--text)); margin: 0.85rem auto 0; padding-left: 0.9rem; border-left: 2px solid var(--clay); color: var(--ink-soft); font-size: 0.92rem; font-weight: 500; line-height: 1.45; }
.prose .figure-wide figcaption { width: var(--column); }
.prose .is-portrait figcaption { width: auto; margin-left: 0; }

/* Article draft: a described photo, not yet generated. Production refuses it. */
.image-draft { display: grid; align-content: center; gap: 0.5rem; padding: clamp(1.25rem, 4vw, 2.5rem); border: 2px dashed rgba(37, 37, 31, 0.22); color: var(--ink-soft); background: var(--surface); font-size: 0.92rem; line-height: 1.5; }
.image-draft strong { color: var(--moss); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; }
.prose .image-draft p { margin: 0; color: inherit; text-align: start; }
/* A draft lead photo fills the photo's box; its words sit above the title. */
.art-photo .image-draft { height: 100%; align-content: start; }
.post-card .image-draft { aspect-ratio: 4 / 3; border-radius: var(--radius-sm); }
.post-list .post-card .image-draft { aspect-ratio: 3 / 2; border-radius: var(--radius-md); }

/* ---------- tables ----------
   The wide column, scrolling sideways on a phone rather than squeezing. */
.prose .table-scroll { grid-column: wide; overflow-x: auto; margin: 0.75rem 0 2rem; }
.prose table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: 0.92rem; line-height: 1.45; }
.prose caption { padding-bottom: 0.75rem; color: var(--ink-soft); font-size: 0.86rem; text-align: start; }
.prose th, .prose td { padding: 0.7rem 0.9rem 0.7rem 0; border-bottom: 1px solid var(--line); text-align: start; vertical-align: top; }
.prose thead th { color: var(--ink-soft); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; }
.prose tbody th { color: var(--ink); font-weight: 650; }
.prose td { color: var(--ink-body); font-variant-numeric: tabular-nums; }

/* ---------- before/after slider (behaviour in site.js) ----------
   The after photo sits in the flow and gives the slider its height; a square
   pair is shown landscape, so no slider is taller than the screen. */
.compare { --pos: 50%; position: relative; overflow: hidden; border-radius: var(--radius-sm); background: var(--surface-deep); touch-action: pan-y; cursor: ew-resize; user-select: none; -webkit-user-select: none; }
.compare > img { width: 100%; height: auto; pointer-events: none; }
.figure-slider:not(.is-portrait) .compare > img { aspect-ratio: 3 / 2; object-fit: cover; }
/* The before photo fills exactly the after photo's box, or the two crop
   differently and stop lining up. */
.compare-before { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--pos)) 0 0); transition: clip-path 220ms var(--ease-out); }
.compare-before img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.compare-divider { position: absolute; inset: 0; pointer-events: none; transform: translateX(calc(var(--pos) - 50%)); transition: transform 220ms var(--ease-out); }
.compare-divider::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; margin-left: -1px; background: #fff; box-shadow: 0 0 6px rgba(0, 0, 0, 0.18); }
.compare[data-dragging] .compare-before, .compare[data-dragging] .compare-divider { transition: none; }
.compare-knob { position: absolute; top: 50%; left: 50%; width: 2.75rem; height: 2.75rem; border-radius: 50%; background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2325251f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 7l-5 5 5 5M15 7l5 5-5 5'/%3E%3C/svg%3E") center / 1.3rem no-repeat; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18); transform: translate(-50%, -50%); pointer-events: auto; }
.compare-label { position: absolute; top: 1rem; left: 1rem; padding: 0.3rem 0.7rem; border-radius: 999px; color: var(--ink); background: rgba(253, 251, 247, 0.92); font-size: 0.75rem; font-weight: 650; }
.compare-label-after { right: 1rem; left: auto; }

/* ---------- share ---------- */
.share { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; width: var(--column); margin: 0.5rem auto 0; }
.share-button {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.9rem;
  padding: 0 1.3rem 0 1.1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 640;
  cursor: pointer;
  transition: border-color 150ms ease;
}
.share-button:hover { border-color: var(--ink-soft); }
.share-button:active { transform: scale(0.97); }
.share-icon { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* When the copy fails it shows the link itself: it may wrap anywhere, and one tap selects all of it. */
.share-status { min-width: 0; overflow-wrap: anywhere; color: var(--ink-soft); font-size: 0.88rem; user-select: all; -webkit-user-select: all; }
/* Without script the button can do nothing, so it stays hidden. */
.share[hidden] { display: none; }

/* ---------- related articles, call to action ---------- */
.next { width: var(--wide); margin: clamp(3rem, 7vw, 5rem) auto 0; }

.post-card { display: grid; grid-template-columns: minmax(0, 15rem) 1fr; gap: clamp(1rem, 3vw, 2rem); align-items: center; text-decoration: none; }
.post-card img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-deep); transition: transform 300ms var(--ease-out); }
.post-card:hover img { transform: scale(1.02); }
.post-card small { color: var(--moss); font-size: 0.74rem; font-weight: 720; letter-spacing: 0.1em; text-transform: uppercase; }
.post-card h3, .post-card h2 { margin: 0.35rem 0 0.4rem; font-size: clamp(1.3rem, 2.4vw, 1.8rem); font-weight: 640; letter-spacing: -0.02em; line-height: 1.15; }
.post-card p { margin: 0; color: var(--ink-soft); }
/* Related articles: one grid of three columns. Every card has a label slot; the
   first card of a group ("Mentioned in this article", "Keep reading") fills it,
   and the group's rule runs across its cards and the gaps between them. On a
   phone the cards stack. */
.next-list { --next-gap: clamp(1.75rem, 3vw, 2.5rem); display: grid; gap: var(--next-gap); }
.next-group { min-height: 1px; margin: 0 0 1rem; padding-top: 0.8rem; border-top: 1px solid var(--line); color: var(--ink-soft); font-size: 0.76rem; font-weight: 760; letter-spacing: 0.12em; line-height: 1.3; text-transform: uppercase; }
.next-item > span.next-group { display: none; }
@media (min-width: 48rem) {
  .next-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .next-item { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; }
  .next-item > span.next-group { display: block; }
  .next-item:not(.group-end):not(:nth-child(3n)) > .next-group { margin-right: calc(-1 * var(--next-gap)); }
}
.next .post-card { grid-template-columns: 1fr; align-content: start; gap: 0.9rem; }
.next .post-card img, .next .post-card .image-draft { aspect-ratio: 3 / 2; }
.next .post-card h3 { font-size: clamp(1.15rem, 1.7vw, 1.35rem); }
.next .post-card p { font-size: 0.92rem; line-height: 1.5; }

/* A full-width band over the post's own photo. */
.cta { position: relative; overflow: hidden; display: grid; align-content: end; min-height: 70svh; margin: clamp(3rem, 7vw, 5rem) 0 0; padding: clamp(2rem, 6vw, 4rem); color: #fff; background: rgb(var(--scrim)); }
.cta-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cta::before { content: ""; position: absolute; z-index: 1; inset: 0; background: linear-gradient(to top, rgba(var(--scrim), 0.85), rgba(var(--scrim), 0.2)); }
.cta-text { position: relative; z-index: 2; width: var(--wide); margin-inline: auto; }
.cta h2 { max-width: 14ch; margin: 0; font-size: clamp(2rem, 4.6vw, 3.4rem); font-weight: 640; letter-spacing: -0.03em; line-height: 1.02; }
.cta p { margin: 1rem 0 0; color: rgba(255, 255, 255, 0.8); }
.cta .store-badge { display: inline-block; margin: 1.8rem 0 0; padding: 0.7rem 1.1rem; border-radius: 999px; color: var(--ink); background: var(--surface); font-size: 0.88rem; font-weight: 650; }

/* ---------- blog index ---------- */
.post-list { display: grid; gap: clamp(2rem, 4vw, 3rem); width: var(--wide); margin: clamp(3rem, 7vw, 5rem) auto; }
.post-list .post-card { grid-template-columns: minmax(0, 1.1fr) 1fr; }
.post-list .post-card img { aspect-ratio: 3 / 2; border-radius: var(--radius-md); }

/* ---------- footer ---------- */
.blog-footer { padding: 2.5rem var(--gutter) calc(2.5rem + env(safe-area-inset-bottom, 0px)); color: var(--ink-soft); font-size: 0.85rem; text-align: center; }
.blog-footer p { margin: 0.3rem 0; }
.blog-footer a { color: var(--ink); text-decoration: none; }
/* The first line leads back into the blog; the second is the legal pages, quieter. */
.blog-footer p:first-child a:first-child { font-weight: 700; }
.blog-footer p + p a { color: var(--ink-soft); }

/* ---------- the app, named in the text ----------
   Every mention of RoomDecor in an article leads to the App Store section of
   the home page. */
.app-link { color: inherit; font-weight: 640; text-decoration: underline; text-decoration-color: var(--clay); text-decoration-thickness: 2px; text-underline-offset: 0.22em; white-space: nowrap; }
.app-link:hover { text-decoration-color: currentColor; }

@media (max-width: 560px) {
  .post-card, .post-list .post-card { grid-template-columns: 1fr; }
}

/* The photo settles and the title lines rise in once, on arrival only. */
@media (prefers-reduced-motion: no-preference) {
  .art-photo img { animation: blog-settle 1600ms var(--ease-out) both; }
  .art-title > * { animation: blog-rise 700ms var(--ease-out) both; }
  .art-title > :nth-child(2) { animation-delay: 100ms; }
  .art-title > :nth-child(3) { animation-delay: 200ms; }
  .art-title > :nth-child(4) { animation-delay: 300ms; }
}
@keyframes blog-settle { from { transform: scale(1.06); } to { transform: none; } }
@keyframes blog-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

@media print {
  .masthead, .read-progress, .share, .cta, .next, .blog-footer { display: none !important; }
  body { background: #fff; }
  .art-head { height: auto; color: var(--ink); }
  .art-photo { display: none; }
  .art-title { position: static; }
  .eyebrow, .dek { color: var(--ink-soft); }
}
