/*
 * Sobuu blog base styles.
 *
 * Hugo builds a separate static site from the Nuxt app and can't consume the
 * Nuxt Tailwind build, so the brand palette is duplicated here as plain CSS
 * custom properties, ported 1:1 from theme/tokens.ts. Keep these two token
 * sets in sync by hand if the palette ever changes.
 */
:root {
  --color-primary: #79aea3; /* GreenSheen — theme/tokens.ts colors.primary */
  --color-background: #f6fbff; /* WhiteBlue — theme/tokens.ts colors.background */
  --color-secondary: #483c32; /* DarkLava — theme/tokens.ts colors.secondary */
  --color-tertiary: #969a97; /* SpanishGray — theme/tokens.ts colors.tertiary */
  --color-error: #cd4631; /* Vermilion — theme/tokens.ts colors.error */
  --color-page-background: #faf6f1; /* Warm ivory, blog-only — deliberately NOT WhiteBlue (--color-background), since app screenshots embedded in posts already use that as their own background and would blend into the page. */
  --font-solway:
    'Solway', serif; /* theme/tokens.ts fontFamily.solway — display/headlines */
  --font-sans:
    'Source Sans 3', system-ui, sans-serif; /* theme/tokens.ts fontFamily.sans — body */
  --shadow-card: 0 2px 8px rgba(72, 60, 50, 0.06), 0 12px 32px rgba(72, 60, 50, 0.1); /* theme/tokens.ts shadow.card */
  --shadow-hero: 0 20px 60px rgba(72, 60, 50, 0.18); /* theme/tokens.ts dropShadow.hero — unused in this stylesheet, kept for parity in case the blog ever needs the hero shadow */
  --font-size-display: 64px; /* theme/tokens.ts fontSize.display */
}

/* Source Sans 3, self-hosted — same TTFs as the main Nuxt site
   (app/assets/fonts/), mounted into this build via hugo.toml's
   [[module.mounts]]. Only the weights/styles post body text actually needs
   (regular, italic, bold, bold-italic) — the rest of the font family's
   weights stay unreferenced here even though the whole directory is
   mounted, since @font-face is lazy: an unreferenced file is never
   downloaded by the browser. */
/* Solway bold — the ONLY weight the blog actually uses, and (matching the
   main app's SobuuLogo.vue) reserved for the "Sobuu" wordmark in
   .blog-header__brand-name alone. Post/featured titles use --font-sans
   instead. Same gap as Source Sans 3 above: font-family: var(--font-solway)
   was already set on the wordmark, but with no @font-face it was silently
   rendering in the fallback serif, not Solway. */
@font-face {
  font-family: 'Solway';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/solway_bold.ttf') format('truetype');
}

@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/source_sans3_regular.ttf') format('truetype');
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/source_sans3_it.ttf') format('truetype');
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/source_sans3_bold.ttf') format('truetype');
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/source_sans3_bold_it.ttf') format('truetype');
}

/* min-height + column flex keeps .blog-footer pinned to the viewport bottom
   on short pages (e.g. a list with only 1-2 posts) instead of ending right
   after the content, partway up the screen. .blog-main's flex: 1 0 auto
   (below) is what actually absorbs the leftover space. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-page-background);
  color: var(--color-secondary);
  font-family: var(--font-sans);
}

/* The rendered markdown body of a single post — see
   layouts/blog/page.html's .blog-post__body wrapper around {{ .Content }}.
   Scoped here (not on .blog-post or body) so it doesn't also resize the
   title, byline, or header/nav elsewhere on the page. */
/* 75% of the column, centered — at least a quarter smaller than the
   column-filling width images rendered at before. max-width:100% is the
   floor for viewports narrower than the image itself. */
.blog-post__body img {
  display: block;
  width: 75%;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}

.blog-post__body {
  font-family: var(--font-sans);
  font-size: 1.125rem;
  line-height: 1.7;
  text-align: justify;
  /* Justify alone can force ugly, uneven word-gaps on narrow lines — hyphens
     lets the browser break long words instead of stretching whitespace to
     fill the line. Works per-page since every post page sets <html lang>. */
  hyphens: auto;
}

.blog-header__brand {
  display: inline-flex;
  /* Bottom-align "Sobuu" and "Blog" regardless of their different font
     sizes — flex's own baseline alignment ignores font metrics the way
     plain inline vertical-align:baseline does, so flex-end is what actually
     keeps their visual bottoms flush. */
  align-items: flex-end;
  gap: 0.35rem;
}

/* "Sobuu" — matches app/components/atoms/SobuuLogo.vue on the main site:
   Solway Bold, Dark Lava (--color-secondary), not the header's own
   background color. Bumped up from the shared 1.5rem the two used to share.
   A real <a> to the main WEBSITE's home (not the blog index) — see
   baseof.html's comment — so text-decoration:none is set HERE, not just on
   the .blog-header__brand wrapper: a child <a>'s own text-decoration comes
   from the browser's UA stylesheet, which a parent's text-decoration does
   not override. */
.blog-header__brand-name {
  color: var(--color-secondary);
  font-family: var(--font-solway);
  font-weight: 700;
  font-size: 1.75rem;
  line-height: 1;
  text-decoration: none;
}

/* "Blog" — body sans font (not Solway, which is reserved for the wordmark
   and post headings), same Dark Lava color as the rest of the site's nav
   text, smaller than "Sobuu" and bottom-aligned with it via the flex parent.
   Its own <a> to the blog index — see .blog-header__brand-name's comment on
   why text-decoration:none must be set on each link, not just the wrapper. */
.blog-header__brand-label {
  color: var(--color-secondary);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.05rem;
  line-height: 1;
  text-decoration: none;
}

/* 48rem so the content box (max-width minus the 1.5rem side padding below)
   comes out to 720px — the width post images are resized to (see the blog
   post images' own resize step) — so inline screenshots fill the text
   column edge-to-edge instead of overflowing it or leaving it narrower. */
.blog-main {
  max-width: 48rem;
  margin: 0 auto;
  padding: 2rem 1.5rem;
  flex: 1 0 auto;
  width: 100%;
  box-sizing: border-box;
}

/* The list page (featured post + grid) needs more horizontal room than a
   single post's comfortable reading line-length — wide enough for 3 grid
   columns at the "hero" breakpoint below. Single posts keep .blog-main's
   narrower 48rem. */
.blog-main--list {
  max-width: 64rem;
}

/* Visually hidden but still present for screen readers/SEO structure — used
   where a heading would otherwise repeat text already visible elsewhere on
   the page (e.g. the list page's "Blog" <h1>, redundant with the header
   brand). Standard clip-based technique, not display:none (which screen
   readers also skip). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Featured post: the newest entry, given a large hero treatment above the
   grid of older posts — see the design comment in layouts/blog/section.html
   for why this fits a low (1-2 posts/month) publishing cadence better than
   a plain grid or masonry layout. */
.blog-featured {
  display: block;
  box-sizing: border-box;
  margin-bottom: 2.5rem;
  padding: 1rem;
  color: inherit;
  text-decoration: none;
}

.blog-featured:hover .blog-featured__title {
  text-decoration: underline;
}

.blog-featured__image {
  display: block;
  width: 100%;
  max-height: 24rem;
  object-fit: cover;
  border-radius: 0.75rem;
  margin-bottom: 1rem;
}

.blog-featured__title {
  display: block;
  color: var(--color-secondary);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.75rem;
}

/* Responsive grid for every post except the featured one: 1 column on
   mobile, 2 from "md", 3 from "hero" — the SAME breakpoints
   theme/tokens.ts's `screens.md`/`screens.hero` use on the main Nuxt site,
   kept in sync by hand like the color/font tokens above. */
.blog-post-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

@media (min-width: 600px) {
  .blog-post-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1000px) {
  .blog-post-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* The whole card (image + title) is one link, so either can be clicked to
   open the post — an <img> alone isn't focusable/clickable on its own.
   Always gets a real card background/padding, even when the post has no
   cover image — otherwise a no-image post next to image posts in the same
   grid row would render as bare floating text with no visual boundary. */
.blog-post-list__card {
  display: block;
  height: 100%;
  box-sizing: border-box;
  padding: 1rem;
  background: #fff;
  border-radius: 0.75rem;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  color: inherit;
  text-decoration: none;
}

.blog-post-list__card:hover .blog-post-list__title {
  text-decoration: underline;
}

.blog-post-list__title {
  color: var(--color-primary);
}

.blog-post-list__thumb {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 0.5rem;
  margin-bottom: 0.5rem;
}

.blog-post__cover {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0.5rem;
  margin-bottom: 1.5rem;
}

.blog-post__meta {
  margin: -0.5rem 0 1.5rem;
  color: var(--color-tertiary);
  font-size: 0.9rem;
}

/* One-word topic pill — see layouts/partials/topic-chip.html. Shown on the
   single post page (below the byline) and on every list/featured card
   (below the title), both linking to that topic's filtered view
   (layouts/topics/term.html). */
.blog-topic-chip {
  display: inline-block;
  margin: 0.5rem 0 1rem;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--color-background);
  color: var(--color-primary);
  font-size: 0.8rem;
  font-weight: 700;
  text-decoration: none;
}

.blog-topic-chip:hover {
  background: var(--color-primary);
  color: var(--color-background);
}

/* On a card, the chip sits directly under the title with no extra top gap
   from .blog-post__meta's negative margin trick (that's post-page only). */
.blog-post-list__card + .blog-topic-chip,
.blog-featured + .blog-topic-chip {
  margin-top: 0;
}

/* The "Filtering by: X · Show all posts" banner on a topic's filtered list
   page (layouts/topics/term.html) — the ONLY way back to the unfiltered
   list from there, since there's no "browse all topics" index page. */
.blog-filter-bar {
  margin: -0.5rem 0 1.5rem;
  color: var(--color-tertiary);
}

.blog-filter-bar__topic {
  color: var(--color-secondary);
}

.blog-filter-bar__clear {
  margin-left: 0.75rem;
  font-weight: 700;
}

.blog-share {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--color-tertiary);
}

.blog-share__label {
  display: block;
  margin-bottom: 0.75rem;
  font-weight: 700;
}

.blog-share__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-right: 0.5rem;
  border-radius: 999px;
  color: var(--color-secondary);
  background: var(--color-background);
}

.blog-share__link:hover {
  background: var(--color-primary);
  color: var(--color-background);
}

.blog-share__link svg {
  width: 1.25rem;
  height: 1.25rem;
}

a {
  color: var(--color-primary);
}

/* --- Nav (mirrors app/components/menu/TopMenu.vue) --- */
.blog-nav {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding-left: 1.5rem;
  background: var(--color-primary);
  box-shadow: 0 6px 20px rgba(72, 60, 50, 0.1);
}
.blog-nav__links {
  display: flex;
  align-items: center;
  gap: 7px;
}
.blog-nav__link {
  padding: 34px 15px;
  color: var(--color-secondary);
  font-family: var(--font-sans);
  font-size: 20px;
  text-decoration: none;
}
.blog-nav__link:hover {
  opacity: 0.7;
}
.blog-nav__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 17px;
  padding: 8px 24px;
  border-radius: 999px;
  background: var(--color-error);
  color: var(--color-background);
  font-family: var(--font-sans);
  font-size: 20px;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(72, 60, 50, 0.04), 0 6px 20px rgba(72, 60, 50, 0.08);
}
.blog-nav__toggle {
  display: none;
}
.blog-nav__toggle summary {
  list-style: none;
  cursor: pointer;
  padding: 20px;
  color: var(--color-secondary);
}
.blog-nav__toggle summary::-webkit-details-marker {
  display: none;
}
.blog-nav__toggle[open] .blog-nav__mobile-panel {
  display: flex;
}
.blog-nav__mobile-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--color-secondary);
  color: var(--color-background);
  padding: 8px 0;
}
.blog-nav__mobile-panel a {
  width: 100%;
  padding: 10px 0;
  text-align: center;
  color: inherit;
  text-decoration: none;
}
@media (min-width: 840px) {
  .blog-nav__cta:not(.blog-nav__cta--desktop) {
    display: none;
  }
}
@media (max-width: 839.98px) {
  .blog-nav__links,
  .blog-nav__cta--desktop {
    display: none;
  }
  .blog-nav__toggle {
    display: block;
  }
}

/* --- Footer (mirrors app/components/footer/SiteFooter.vue) --- */
.blog-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  border-top: 1px solid rgba(72, 60, 50, 0.1);
  padding-bottom: 20px;
  background: var(--color-page-background);
}
.blog-footer__social {
  display: flex;
  gap: 60px;
  padding: 40px 30px 0;
}
.blog-footer__social a {
  color: var(--color-secondary);
}
.blog-footer__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  color: var(--color-secondary);
  font-family: var(--font-sans);
  font-size: 16px;
}
.blog-footer__links a {
  padding: 15px 0;
  color: inherit;
  text-decoration: none;
}
.blog-footer__links a:hover {
  text-decoration: underline;
}
@media (min-width: 840px) {
  .blog-footer {
    flex-direction: row;
    border-top: none;
    padding: 18px 8% 18px 30px;
    background: var(--color-primary);
  }
  .blog-footer__social {
    padding: 0;
  }
  .blog-footer__links {
    flex: 1;
    flex-direction: row;
    justify-content: center;
    gap: 48px;
    padding: 0;
  }
  .blog-footer__links a {
    padding: 0;
  }
}

/* --- Shared card language (mirrors LegalPage.vue / FeaturesLine.vue) --- */
.blog-card {
  border-radius: 20px;
  background: #fff;
  box-shadow: var(--shadow-card);
}

/* Single-post title. Sans (not Solway, reserved for the wordmark — see
   .blog-header__brand-name above) and sized for a 42rem reading column, not
   the marketing hero's oversized --font-size-display. */
.blog-post__title {
  font-family: var(--font-sans);
  font-size: 2.25rem;
  line-height: 1.25;
  font-weight: 700;
}

@media (max-width: 480px) {
  .blog-post__title {
    font-size: 1.75rem;
  }
}
