/* ============================================================
   Lukman Batik — blog.css

   Loaded AFTER the main site's styles.css (see lib/layout.php), so the tokens, the
   fonts and the button system all arrive already defined and this file only adds what
   a long article needs on top.

   TWO THINGS THE SITE'S CSS DOES THAT EVERY RULE BELOW HAS TO WORK AROUND:

   1. styles.css rule 1 zeroes border-radius GLOBALLY with
        *, *::before, *::after { border-radius: 0 !important }
      so every rounded corner here has to be re-granted by class name, also with
      !important. Rounded corners are the design language (Agung, 2026-09-06:
      "ingat bahasa design kita rounded corner") — a radius written without
      !important silently does nothing.

   2. Buttons are OUTLINE at rest and go --rollover pink with BLACK text on hover
      (Agung, 2026-09-06: "harusnya outline as idle, baru hover pink, semua button
      harus kek gtu"). Orange is a SURFACE colour, never a button fill.

   TYPE NOTE, worth knowing before you read a 1500-word post on a phone: the whole site
   is set in Roboto Mono, and this page keeps that rather than introducing a second
   family for one section. Mono is hard work at length, so the measure is narrowed to
   ~62 characters and the leading opened to 1.85 — that is what makes it readable.
   If it still reads heavy, the one-line fix is to give `.blog-prose` a proportional
   stack; everything else here is independent of that choice.
   ============================================================ */

.blog-body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
}

/* ---------- top bar ----------
   Gone on purpose. The header is now the main site's own .topbar markup (see lib/layout.php),
   styled entirely by styles.css, so the blog and the homepage cannot drift apart. The
   .blog-top / .blog-brand / .blog-nav / .blog-book rules that used to live here were a
   lookalike, and a lookalike is a second thing to keep in sync forever.

   One rule survives: the sticky header needs to clear the phone's safe area. */
.topbar { top: env(safe-area-inset-top, 0px); }

.blog-main { max-width: 1120px; margin: 0 auto; padding: clamp(28px, 5vw, 64px) clamp(16px, 4vw, 40px) 80px; }

/* ---------- list hero ---------- */
.blog-hero { text-align: center; margin-bottom: clamp(32px, 5vw, 56px); }
.blog-eyebrow {
  font: 500 11px/1 var(--sans);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted-2);
  margin-bottom: 14px;
}
/* THE FONT TRAP. styles.css carries
     h1, h2, h3, .hero-title, … { font-family: var(--display) !important }
   so every heading on this page is handwriting (Caveat) unless it says otherwise with
   its own !important. Measured, not assumed: the article sub-headings came out in
   Caveat at a size that read SMALLER than the body text around them.
   The split below is deliberate:
     - display (Caveat) for the big one-off titles — hero, post title, CTA
     - mono bold for anything that gets SCANNED — card titles, in-article h2/h3
   Handwriting is a voice, not a wayfinding tool. */
.blog-hero h1 {
  font-family: var(--display) !important;
  font-weight: 700;
  font-size: clamp(40px, 7vw, 68px);
  line-height: 1.05;
  margin: 0 0 14px;
  color: var(--ink);
}
.blog-tagline {
  font: 400 14px/1.7 var(--sans);
  color: var(--muted);
  max-width: 54ch; margin: 0 auto;
}

/* ---------- card list ---------- */
.blog-list {
  display: grid;
  /* minmax(0, …) not 1fr: an auto floor is min-content, which is what let a long
     unbroken word push a card wider than its column on a small phone. */
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: clamp(18px, 2.6vw, 28px);
}
.blog-list > * { min-width: 0; }

.blog-card {
  border: 1px solid var(--line);
  border-radius: var(--r-lg) !important;
  overflow: hidden;
  background: var(--card);
  display: flex; flex-direction: column;
  transition: transform .18s ease, box-shadow .18s ease;
}
.blog-card:hover { transform: translateY(-3px); box-shadow: 0 10px 0 -4px rgba(10,12,27,.12); }
.blog-card-img { display: block; aspect-ratio: 16 / 10; overflow: hidden; line-height: 0; }
.blog-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-body { padding: clamp(16px, 2vw, 22px); display: flex; flex-direction: column; gap: 10px; flex: 1 1 auto; }

.blog-meta {
  font: 500 11px/1.4 var(--sans);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted-2);
}
.blog-card-title { margin: 0; font: 700 19px/1.35 var(--sans); font-family: var(--sans) !important; }
.blog-card-title a { color: var(--ink); text-decoration: none; }
.blog-card-title a:hover { color: var(--rollover); }
.blog-card-excerpt { margin: 0; font: 400 13.5px/1.75 var(--sans); color: var(--muted); }
.blog-readmore {
  margin-top: auto;
  font: 500 12px/1 var(--sans);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 3px; align-self: flex-start;
}
.blog-readmore:hover { color: var(--rollover); border-color: var(--rollover); }

/* ---------- buttons ---------- */
.blog-btn {
  display: inline-block;
  border: 1px solid var(--line);
  border-radius: 999px !important;
  padding: 12px 22px 11px;
  font: 500 12px/1 var(--sans);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink); background: transparent;
  text-decoration: none; cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.blog-btn:hover { background: var(--rollover); color: #000; }
/* ---------- empty / pager ---------- */
.blog-empty {
  border: 1px dashed var(--hairline);
  border-radius: var(--r-lg) !important;
  padding: clamp(32px, 6vw, 64px) 24px;
  text-align: center;
}
.blog-empty p { font: 400 14px/1.7 var(--sans); color: var(--muted); margin: 0 0 20px; }
.blog-empty h1 { font-family: var(--display) !important; font-size: clamp(30px, 5vw, 44px); margin: 0 0 10px; }

.blog-pager { display: flex; align-items: center; justify-content: center; gap: 18px; margin-top: 44px; flex-wrap: wrap; }
.blog-pageno { font: 500 11px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--muted-2); }

/* ---------- single post ---------- */
/* The article sits on a WHITE panel rather than straight on the page. styles.css puts a
   batik watermark on <body> with !important, and while that texture is right for the
   marketing pages, it was showing through between the lines of a 700-word article set in
   mono. Texture stays in the margins; the reading column is clean. Same white-panel-on-
   pattern treatment the cards on the index already use, so it is not a new idea. */
.blog-post {
  max-width: 800px; margin: 0 auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg) !important;
  padding: clamp(22px, 4vw, 46px);
}
.blog-post .blog-prose { margin-left: auto; margin-right: auto; }
/* Replaces the old single .blog-back link. Same type treatment — small uppercase mono in
   --muted — so nothing about the page's rhythm changed; it just carries two steps now. */
.blog-crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: 22px;
  font: 500 11px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.blog-crumbs a { color: var(--muted); text-decoration: none; }
.blog-crumbs a:hover { color: var(--rollover); }
.blog-crumbs span { color: var(--line); }
.blog-post-title {
  font-family: var(--display) !important; font-weight: 700;
  font-size: clamp(34px, 5.6vw, 56px); line-height: 1.08;
  margin: 10px 0 26px; color: var(--ink);
}
.blog-cover { margin: 0 0 34px; border-radius: var(--r-lg) !important; overflow: hidden; line-height: 0; border: 1px solid var(--line); }
.blog-cover img { width: 100%; height: auto; display: block; }

/* A draft is only ever visible to a logged-in admin, and it says so loudly — the worst
   outcome would be mistaking an unfinished post for the live one. */
.blog-draft {
  border: 1px solid var(--line);
  border-radius: var(--r-md) !important;
  background: var(--if-yellow);
  padding: 12px 16px; margin-bottom: 24px;
  font: 500 12px/1.6 var(--sans);
}

/* ---------- prose ---------- */
.blog-prose {
  max-width: 62ch;
  font: 400 16px/1.85 var(--sans);
  color: var(--text);
}
/* SPACING IS OWNED BY THE FLOW, NOT BY THE ELEMENTS — see the long note in
   admin/admin.css. Short version: `.blog-prose p { margin: 0 }` is (0,1,1) and silently
   beats `.blog-prose > * + *` (0,1,0), which cost every paragraph its gap. One rule
   zeroes, one sets the rhythm, exceptions are `> * + tag` / `> tag + *`. */
.blog-prose > * { margin: 0; }
.blog-prose > * + * { margin-top: 1.35em; }
.blog-prose > * + h2 { margin-top: 2.2em; }
.blog-prose > * + h3 { margin-top: 1.9em; }
/* A heading belongs to the text under it, so it sits closer to that than to what came before. */
.blog-prose > h2 + *, .blog-prose > h3 + * { margin-top: .7em; }
.blog-prose > * + hr, .blog-prose > hr + * { margin-top: 2.4em; }

.blog-prose h2 { font: 700 25px/1.3 var(--sans); font-family: var(--sans) !important; color: var(--ink); }
.blog-prose h3 { font: 700 18px/1.4 var(--sans); font-family: var(--sans) !important; }
.blog-prose a { color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.blog-prose a:hover { color: var(--rollover); }
.blog-prose strong { font-weight: 700; }
.blog-prose ul, .blog-prose ol { padding-left: 1.4em; }
.blog-prose li + li { margin-top: .5em; }
.blog-prose blockquote {
  padding: 18px 22px;
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--r-md) !important;
  background: #FBFAF7;
  font-style: normal; color: var(--muted);
}
.blog-prose blockquote > * { margin: 0; }
.blog-prose blockquote > * + * { margin-top: 1em; }
.blog-prose pre {
  border: 1px solid var(--line);
  border-radius: var(--r-md) !important;
  background: #FBFAF7;
  padding: 16px 18px; overflow-x: auto;
  font-size: 13px; line-height: 1.7;
}
.blog-prose code { font-family: var(--sans); font-size: .92em; }
.blog-prose img {
  max-width: 100%; height: auto; display: block;
  border-radius: var(--r-md) !important;
  border: 1px solid var(--hairline);
}
.blog-prose hr { border: 0; border-top: 1px solid var(--hairline); }

/* ---------- post CTA ----------
   Nothing here any more. The booking ask at the foot of an article is the homepage's own
   `.cta-band`, which lives in styles.css — see blog_cta() in lib/layout.php. The old
   `.blog-cta` / `.blog-btn-solid` rules were deleted rather than left behind: this file is
   small on purpose, and a dead rule that still looks like the live one is how a later edit
   ends up styling a block nothing renders. */

/* ---------- earlier / later ----------
   Two tiles below the article. Sits between the prose and the booking CTA, so a reader who
   finished the piece is offered another one before being asked to buy anything.

   grid rather than flex: with two auto columns both tiles are exactly the same width no
   matter how long the two titles are, and the FIRST post (no "earlier") or the LAST one
   (no "later") gets a single full-width tile instead of a lonely half. */
.blog-neighbours {
  max-width: 820px; margin: 26px auto 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px;
}
.blog-neighbour {
  display: block; padding: 16px 18px;
  border: 1px solid var(--line); background: #fff;
  border-radius: var(--r-md) !important;
  text-decoration: none; transition: border-color .18s ease, transform .18s ease;
}
.blog-neighbour:hover { border-color: var(--ink); transform: translateY(-2px); }
.blog-neighbour-dir {
  display: block; margin-bottom: 7px;
  font: 500 10px/1 var(--sans); letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
}
.blog-neighbour-title { display: block; font: 700 15px/1.4 var(--sans); color: var(--ink); }
.blog-neighbour:hover .blog-neighbour-title { color: var(--rollover); }
/* "Later →" is set flush right so the pair reads outwards from the middle — but only when
   the two tiles genuinely share a row.
   Two guards, because there are two different ways it ends up alone:
   - :only-child — the oldest post has no "earlier", so its single tile stays left.
   - the media query — below ~537px the grid stacks (0.92 × viewport drops under the
     240+240+14 two-column minimum; measured, not guessed), and a right-aligned tile sitting
     under a left-aligned one just looks like a mistake. 540 is the first round number above
     the flip. */
@media (min-width: 540px) {
  .blog-neighbour-next:not(:only-child) { text-align: right; }
}

/* ---------- footer ---------- */
.blog-foot { border-top: 1px solid var(--line); background: var(--if-navy); color: #fff; }
.blog-foot-in {
  max-width: 1120px; margin: 0 auto;
  padding: clamp(28px, 4vw, 44px) clamp(16px, 4vw, 40px);
  display: flex; flex-wrap: wrap; gap: 22px; justify-content: space-between; align-items: flex-start;
}
.blog-foot-name { font: 700 15px/1.3 var(--sans); }
.blog-foot-sub { font: 400 12px/1.7 var(--sans); color: rgba(255,255,255,.7); margin-top: 6px; }
.blog-foot-links { display: flex; flex-wrap: wrap; gap: 18px; }
.blog-foot-links a {
  font: 500 11px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255,255,255,.86); text-decoration: none;
}
.blog-foot-links a:hover { color: var(--if-orange); }
.blog-foot-copy {
  border-top: 1px solid rgba(255,255,255,.14);
  padding: 14px clamp(16px, 4vw, 40px);
  font: 400 11px/1.6 var(--sans); color: rgba(255,255,255,.55);
  text-align: center;
}

@media (max-width: 560px) {
  .blog-prose { font-size: 15.5px; }
}
