/*
 * Public site styles.
 *
 * Purpose: a calm, readable news feed wearing the Cloud Mechanix identity, so a
 * reader arriving from cloudmechanix.com recognises where they are. The palette,
 * the near-square 2px corners and the type scale are taken from that site:
 *
 *   ground   #f4f7fb      ink      #0b1220      muted    #4f535b
 *   rule     #d8dce0      primary  #005a9e      deep     #002b5c
 *
 * Colour tokens are redefined for dark mode, so components are written once.
 * Cloud Mechanix is a light design; the dark palette keeps its navy and blue
 * rather than inventing a second identity.
 *
 * Fonts: Cloud Mechanix sets headings in Archivo and body text in Inter. Both are
 * named first here and fall back to the reader's system fonts, because the
 * Content-Security-Policy loads nothing from third parties. Self-hosting the two
 * open-licence files would make the match exact at the cost of two downloads.
 */

:root {
  --bg: #f4f7fb;
  --surface: #ffffff;
  --text: #0b1220;
  --text-soft: #33465c;
  --muted: #4f535b;
  --border: #d8dce0;
  --accent: #005a9e;
  --accent-soft: #e6eff7;
  --accent-text: #ffffff;
  --deep: #002b5c;
  --danger: #a4262c;
  --radius: 2px;
  --focus: 0 0 0 3px rgba(0, 120, 212, 0.4);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b1220;
    --surface: #111c2e;
    --text: #eaf0f7;
    --text-soft: #b9c6d6;
    --muted: #8a99ab;
    --border: #23314a;
    --accent: #4aa3e0;
    --accent-soft: #11263d;
    --accent-text: #06111f;
    --deep: #0b2b4d;
    --danger: #ff9aa2;
    --radius: 2px;
    --focus: 0 0 0 3px rgba(74, 163, 224, 0.45);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 1rem/1.5 "Inter Variable", Inter, "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-underline-offset: 2px; }
h1, h2, h3 {
  font-family: "Archivo Variable", Archivo, "Inter Variable", Inter, "Segoe UI", system-ui, sans-serif;
  font-weight: 800; letter-spacing: -0.015em; line-height: 1.2;
}
:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--radius); }
[hidden] { display: none !important; }

.wrap { max-width: 56rem; margin: 0 auto; padding: 0 1.25rem; }
.wrap.narrow { max-width: 40rem; }

.masthead { background: var(--surface); border-bottom: 3px solid var(--text); }
.masthead-inner { display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem; align-items: center; justify-content: space-between; padding-top: 0.9rem; padding-bottom: 0.9rem; }
/* The nameplate reads "The Azure Daily by" and then the supplied Cloud Mechanix
   lockup. Two links, because they lead to two places: the title to this paper's
   front page, the logo to the house that publishes it. Their sizes are tied
   together, the logo's height following the title's font size, so neither can run
   away with the page at any viewport. */
.brand {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 0.5rem;
  font-size: clamp(1.1rem, 3.2vw, 1.6rem);
  color: var(--text);
}
.brand-title {
  font-family: "Archivo Variable", Archivo, "Inter Variable", Inter, "Segoe UI", system-ui, sans-serif;
  font-weight: 800; letter-spacing: -0.02em; line-height: 1; white-space: nowrap;
  color: var(--text); text-decoration: none;
}
.brand-title:hover { color: var(--accent); }
.brand-by { font-size: 0.6em; font-weight: 600; color: var(--muted); }
.brand-logo { display: inline-flex; align-self: center; }
.brand-mark {
  height: 1.05em; width: auto; display: block;
  max-width: min(13rem, 50vw);   /* never wider than the phone it is read on */
}

/* The lockup is drawn in ink and navy for light backgrounds. In dark mode it sits
   on its own light plate, which is the artwork's clear-space rule rather than a
   recolouring of someone else's logo. */
@media (prefers-color-scheme: dark) {
  .brand-mark {
    background: #ffffff; padding: 0.2rem 0.3rem; border-radius: var(--radius);
    height: 1.85em; box-sizing: content-box;
  }
}
.account { display: flex; flex-wrap: wrap; gap: 1rem; }
.account-link { font-size: 0.9375rem; }

/* The weekly briefing: a quiet band under the filters, not a pop-up and not a
   bar across the top of the page. It only appears for a signed-in reader. */
.briefing {
  display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem;
  align-items: center; justify-content: space-between;
  margin: 0 0 1.5rem; padding: 1rem 1.15rem;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 4px solid var(--accent); border-radius: var(--radius);
}
.briefing-copy { flex: 1 1 22rem; }
.briefing h2 {
  font-family: "Archivo Variable", Archivo, Inter, system-ui, sans-serif;
  margin: 0 0 0.25rem; font-size: 1.0625rem; letter-spacing: 0.01em;
}
.briefing p { margin: 0; font-size: 0.9375rem; color: var(--muted); max-width: 46rem; }
.briefing .account-button { flex: 0 0 auto; }
.briefing .account-button[disabled] { opacity: 0.6; cursor: default; }

/* The privacy notice, asked once, as a modal. Sized to the words rather than to
   the viewport, so it reads as a question and not as a wall. */
.notice-dialog {
  max-width: 32rem; width: calc(100% - 2rem);
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text); padding: 1.5rem;
}
.notice-dialog::backdrop { background: rgba(11, 18, 32, 0.55); }
.notice-dialog h2 { margin: 0 0 0.6rem; font-size: 1.25rem; }
.notice-dialog p { margin: 0 0 0.75rem; }
.notice-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 1.25rem; }
/* Without dialog support it falls back to a block in the page flow. */
.notice-dialog:not([open]) { display: none; }

/* The sign-in control, and the briefing button, which look the same because they
   do the same kind of thing: one deliberate step the reader chooses to take. */
.account-button {
  display: inline-block; font: inherit; font-size: 0.9375rem; font-weight: 600;
  text-decoration: none; text-align: center;
  color: var(--accent-text); background: var(--accent);
  border: 1px solid var(--accent); border-radius: var(--radius);
  padding: 0.35rem 0.85rem; cursor: pointer;
}
.account-button:hover { background: var(--deep); border-color: var(--deep); color: var(--accent-text); }
.small { font-size: 0.8125rem; }

.intro { padding: 2rem 0 0.5rem; }
.intro h1 { font-size: clamp(1.5rem, 4vw, 2.1rem); line-height: 1.2; margin: 0 0 0.5rem; text-wrap: balance; }
.intro p { color: var(--text-soft); margin: 0; max-width: 42rem; }

.status, .notice { padding: 0.7rem 1rem; border-radius: var(--radius); background: var(--accent-soft); margin: 1rem 0; }
.notice p { margin: 0 0 0.6rem; }

.filter-bar { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin: 1.5rem 0 0.5rem; }
.pills { display: flex; flex-wrap: wrap; gap: 0.4rem; }

button {
  font: inherit; cursor: pointer; border-radius: var(--radius);
  border: 1px solid var(--accent); background: var(--accent); color: var(--accent-text);
  padding: 0.45rem 0.9rem;
}
button.danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.text-button { background: none; border: 0; color: var(--accent); padding: 0.25rem; text-decoration: underline; }

.pill {
  background: var(--surface); color: var(--text-soft); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 0.2rem 0.75rem; font-size: 0.875rem;
}
.pill.on { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }

.count { color: var(--muted); font-size: 0.875rem; margin: 0.5rem 0; }

.article-title { font-size: 1.125rem; line-height: 1.35; margin: 0 0 0.3rem; }
.article-title a { color: var(--text); text-decoration: none; }
.article-title a:hover { text-decoration: underline; }
.attribution { color: var(--muted); font-size: 0.875rem; margin: 0 0 0.5rem; }
/* This service's own summary reads as body text; the publisher's words are set
   apart as a quote, so the two are never mistaken for each other. */
.editorial { margin: 0 0 0.6rem; }
.excerpt { margin: 0 0 0.6rem; padding-left: 0.75rem; border-left: 2px solid var(--border); color: var(--text-soft); font-size: 0.9375rem; }
.label { font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.tags { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; margin: 0 0 0.6rem; }
.tag { font-size: 0.8125rem; background: var(--accent-soft); border-radius: var(--radius); padding: 0 0.45rem; }
.read-original { font-size: 0.9375rem; font-weight: 600; }

.empty { color: var(--muted); }
.more { display: block; margin: 1.25rem auto; }

.facts { display: grid; gap: 0.6rem; margin: 1rem 0; }
.facts div { display: grid; grid-template-columns: 11rem 1fr; gap: 1rem; border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; }
.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.25rem; }

.prose h2 { font-size: 1.15rem; margin: 1.75rem 0 0.4rem; }
.prose .meta { color: var(--muted); }

.footer { border-top: 1px solid var(--border); margin-top: 3rem; padding: 1.25rem 0; color: var(--muted); font-size: 0.875rem; }
.footer p { margin: 0.25rem 0; }
/* The admin link is for the handful of people who can use it, so it sits quietly
   in the footer rather than competing with the feed. */
.admin-link { color: var(--muted); }

@media (max-width: 36rem) {
  .facts div { grid-template-columns: 1fr; gap: 0.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}


/* ---------------------------------------------------------------------------
   The front page.

   A newspaper tells you what matters by how much room it gives a story, so the
   review's prominence decides the deck an article lands in and each deck has its
   own weight. There are two levels and no more: the story that led a day, set
   across the page, and everything else in two columns. The review still grades
   every article more finely than that, and the weekly briefing uses the finer
   grading, but a page with four sizes of story asked a reader to read a ranking
   rather than the news.

   What makes it read as a paper rather than a feed is that hierarchy and the
   dated rule that opens each day, not the absence of an edge around each story.
   --------------------------------------------------------------------------- */

.dateline {
  font-family: "Archivo Variable", Archivo, "Inter Variable", Inter, system-ui, sans-serif;
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 0.35rem;
}

.decks { margin-top: 1rem; }
.deck { list-style: none; margin: 0; padding: 0; }
/* Each day is its own front page, so it opens with a dated rule and keeps a
   headline story of its own all the way down. */
.day { margin-bottom: 2.5rem; }
.day-head {
  font-family: "Archivo Variable", Archivo, Inter, system-ui, sans-serif;
  font-size: 0.8rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted);
  margin: 2.25rem 0 0.75rem; padding-bottom: 0.4rem; border-bottom: 2px solid var(--text);
}
.day:first-child .day-head { margin-top: 0.5rem; }

/* A story is a panel on the page: its own ground, its own edge, and the same
   room on all four sides. The padding is deliberately even. An earlier version
   of this file set the edge in one rule and the padding in another, which left
   the type hard against the border. */
.article {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem;
}

/* Declared after .article on purpose. Both selectors have the same weight, so
   the one written later wins the properties they share: with these rules above
   .article, the band lost its tinted ground and its edge to .article's own
   background and border shorthand, and an advert that looks like a story is
   not an advert. */
/* The Cloud Mechanix banner: a band across the full width of the page, between
   rows of stories rather than inside one. It keeps its own light ground in both
   themes, because the lockup is drawn for a light plate and the wordmark would
   disappear on the dark one. An advert on its own brand ground is also what a
   reader expects, so it reads as an advert and not as a story. */
.ad {
  grid-column: 1 / -1;
  background: #e9f1fb;
  border-color: #cadcf2;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.6rem 1.5rem;
  padding: 1.1rem 1.4rem;
}
.ad-label {
  color: #5b6472; flex-basis: 100%; text-align: center; margin: 0;
}
.ad-link { display: block; line-height: 0; }
.ad-mark { width: min(15rem, 55vw); height: auto; }
.ad-tagline {
  margin: 0; font-size: 1.0625rem; font-weight: 600; color: #0b2545;
  font-family: "Archivo Variable", Archivo, Inter, system-ui, sans-serif;
}
.ad-cta { font-weight: 600; font-size: 0.9375rem; color: #0b5cab; }

/* On a phone the band stacks, which is the only way three items fit. */
@media (max-width: 40rem) {
  .ad { flex-direction: column; text-align: center; }
  .ad-tagline { font-size: 1rem; }
}

/* The headline story of a day, at the same size on every day, so a reader
   scrolling down the page can see at a glance what led each one. */
.deck-headline { margin-bottom: 1.25rem; padding-bottom: 1.25rem; border-bottom: 3px solid var(--text); }
.article-headline .article-title { font-size: clamp(1.5rem, 3.6vw, 2.1rem); line-height: 1.1; }
.article-headline .editorial { font-size: 1.0625rem; max-width: 46rem; }
.article-headline .excerpt { max-width: 44rem; }

/* Everything else, in two columns on a desktop and one on a phone. Three columns
   fit, but each story carries a headline, an attribution line, a summary and a
   quotation, and in a third of the page that measure is too narrow to read: the
   result looked squashed rather than dense. */
.deck-standard { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
.article-standard .article-title { font-size: 1.1875rem; line-height: 1.25; }
.article-standard .excerpt { font-size: 0.9375rem; }

@media (max-width: 40rem) {
  .deck-standard { grid-template-columns: 1fr; }
  /* A phone has no room to spend on side padding, so the panels keep their
     edges but hold the type a little closer. */
  .article { padding: 1rem 1.1rem; }
}
