/* ===========================================================================
   Longtable styles.

   One stylesheet, no framework. Light and dark follow the system setting via
   prefers-color-scheme, so there is a single place where each colour is
   defined and no theme toggle to keep in sync.
   =========================================================================== */

/* Colour tokens live at the foot of this file, under "Visual language".
   They were redefined there when the design changed, and two sets of --accent
   in one stylesheet is a trap for whoever edits it next. */

:root { --max-width: 44rem; }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI",
        Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75rem; }

a { color: var(--accent); }
a:hover { text-decoration-thickness: 2px; }

.skip-link {
  position: absolute; left: -9999px;
  background: var(--surface); padding: .5rem .75rem; border-radius: var(--radius-sm);
}
.skip-link:focus { left: .5rem; top: .5rem; z-index: 50; }

/* --------------------------------------------------------------- layout */

.site-header {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  max-width: var(--max-width); margin: 0 auto; padding: .6rem 1rem;
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
}

.brand {
  display: flex; align-items: center; gap: .5rem;
  font-weight: 650; color: var(--text); text-decoration: none;
}

.brand-mark {
  width: 1.1rem; height: 1.1rem; border-radius: 3px;
  background: var(--accent);
  box-shadow: inset 0 -3px 0 rgb(0 0 0 / 12%);
}

.site-nav { margin-left: auto; display: flex; gap: .25rem; flex-wrap: wrap; }

.site-nav a {
  color: var(--text-dim); text-decoration: none;
  padding: .35rem .6rem; border-radius: var(--radius-sm); font-size: .92rem;
}
.site-nav a:hover { background: var(--surface-alt); color: var(--text); }
.site-nav a[aria-current="page"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.site-main {
  max-width: var(--max-width); margin: 0 auto; padding: 1.25rem 1rem 3rem;
  outline: none;
}


/* ---------------------------------------------------------------- cards */

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem;
  box-shadow: var(--shadow);
}
.card > :last-child { margin-bottom: 0; }
.card-narrow { max-width: 26rem; margin-left: auto; margin-right: auto; }

.card-header {
  display: flex; align-items: baseline; gap: .5rem;
  margin: -.25rem 0 .75rem;
}
.card-header h2, .card-header h3 { margin: 0; }
.card-header .spacer { margin-left: auto; }

.muted { color: var(--text-dim); }
.small { font-size: .85rem; }
.tiny { font-size: .78rem; }
.centered { text-align: center; }
.stack > * + * { margin-top: .6rem; }
.row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.row-tight { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; }

/* --------------------------------------------------------------- forms */

label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .25rem; }

input[type="text"], input[type="email"], input[type="password"],
input[type="search"], textarea, select {
  width: 100%; padding: .55rem .65rem;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit;
}
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
textarea { resize: vertical; min-height: 5rem; }

.field { margin-bottom: .85rem; }
.field-hint { font-size: .8rem; color: var(--text-dim); margin-top: .25rem; }

button, .button {
  display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  padding: .5rem .85rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font: inherit; font-weight: 550; cursor: pointer; text-decoration: none;
}
button:hover:not(:disabled), .button:hover { background: var(--surface-alt); }
button:disabled { opacity: .55; cursor: not-allowed; }

button.primary, .button.primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-text);
}
button.primary:hover:not(:disabled) { filter: brightness(1.08); }

button.danger { color: var(--danger); border-color: var(--danger); }
button.danger:hover:not(:disabled) { background: var(--danger-soft); }

button.link {
  background: none; border: none; padding: 0; color: var(--accent);
  text-decoration: underline; font-weight: 500;
}
button.quiet { background: none; border-color: transparent; color: var(--text-dim); }
button.quiet:hover:not(:disabled) { background: var(--surface-alt); color: var(--text); }
button.small-btn { padding: .25rem .55rem; font-size: .85rem; }

.checkbox-row { display: flex; gap: .5rem; align-items: flex-start; }
.checkbox-row input { margin-top: .3rem; flex: none; width: auto; }
.checkbox-row label { font-weight: 400; margin: 0; }

/* -------------------------------------------------------------- notices */

.banner {
  padding: .75rem 1rem; border-bottom: 1px solid var(--warn-border);
  background: var(--warn-soft); color: var(--text); font-size: .92rem;
}
.banner.danger { background: var(--danger-soft); border-color: var(--danger); }
.banner strong { display: block; margin-bottom: .15rem; }

.notice {
  padding: .6rem .75rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-alt);
  font-size: .9rem; margin-bottom: .85rem;
}
.notice.error { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.notice.ok { background: var(--accent-soft); border-color: var(--accent); }

.toasts {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 40;
  display: flex; flex-direction: column; gap: .5rem; max-width: 22rem;
}
.toast {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm); padding: .6rem .75rem;
  box-shadow: var(--shadow); font-size: .9rem;
}
.toast.error { border-left-color: var(--danger); }

/* ---------------------------------------------------------------- posts */

.post { background: var(--surface); border: 1px solid var(--border);
        border-radius: var(--radius); margin-bottom: .85rem; box-shadow: var(--shadow); }
.post-body { padding: .85rem 1rem .5rem; }
.post-text { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0 0 .5rem; }
.post-image { display: block; max-width: 100%; height: auto; border-radius: var(--radius-sm); margin: 0; }

/* Several images tile; one image is shown whole. The two cases want different
   treatment: a single photograph should not be cropped to fit a grid cell, and
   a set of eight should not be eight screens of scrolling. */
.post-images { display: grid; gap: .35rem; margin: .5rem 0; }
.post-images.multi { grid-template-columns: 1fr 1fr; }
.post-images.multi .post-image { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.post-actions { display: flex; gap: .25rem; align-items: center;
                padding: .35rem .75rem .6rem; border-top: 1px solid var(--border); }
.post-actions .spacer { margin-left: auto; }

.post-author { display: flex; align-items: center; gap: .5rem; margin-bottom: .35rem; }
.post-author a { color: var(--text); text-decoration: none; font-weight: 600; }
.post-author a:hover { text-decoration: underline; }

.avatar {
  width: 2rem; height: 2rem; border-radius: 50%; flex: none;
  background: var(--accent-soft); color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 650; font-size: .85rem; object-fit: cover;
  border: 1px solid var(--border);
}
.avatar-lg { width: 3.5rem; height: 3.5rem; font-size: 1.3rem; }
.avatar-sm { width: 1.6rem; height: 1.6rem; font-size: .7rem; }

.post.removed { background: var(--surface-alt); }
.post.removed .post-body { color: var(--text-dim); }

.tombstone { font-style: italic; color: var(--text-dim); }

.comment { padding: .5rem 0 0; border-top: 1px solid var(--border); margin-top: .5rem; }
.comment:first-child { border-top: none; margin-top: 0; }
.comment .comment-head { display: flex; align-items: center; gap: .4rem; }
.comment-body { white-space: pre-wrap; overflow-wrap: anywhere; margin: .2rem 0 0; font-size: .95rem; }

.comment-form { display: flex; gap: .5rem; margin-top: .6rem; }
.comment-form textarea { min-height: 2.6rem; }

/* Editing happens where the text was, so the box is sized like the paragraph
   it replaces rather than like the 5rem form field a textarea defaults to. */
.post-edit textarea { min-height: 3.4rem; }

/* --------------------------------------------------------------- people */

.person {
  display: flex; align-items: center; gap: .6rem;
  padding: .6rem 0; border-bottom: 1px solid var(--border);
}

/* An unread notification is marked by a rule down its side rather than by a
   background, so that it reads as new without shouting. */
.person.unread { border-left: 3px solid var(--accent); padding-left: .6rem; }
.person.unread .person-info .small { font-weight: 600; }
.person:last-child { border-bottom: none; }
.person-info { min-width: 0; }
.person-info strong { display: block; }
.person .spacer { margin-left: auto; }

.stats { display: flex; gap: 1.25rem; margin: .5rem 0 0; }
.stats div { font-size: .85rem; color: var(--text-dim); }
.stats strong { display: block; color: var(--text); font-size: 1rem; }

/* ---------------------------------------------------------------- verse */

.verse { background: var(--accent-soft); border: 1px solid var(--border); }
.verse blockquote { margin: 0; font-size: 1.05rem; line-height: 1.6; }
.verse .ref { font-weight: 650; color: var(--accent); margin-top: .5rem; }

/* ---------------------------------------------------------------- admin */

.table-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: .9rem; }
th, td { text-align: left; padding: .45rem .5rem; border-bottom: 1px solid var(--border);
         vertical-align: top; }
th { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-dim); }

.pill {
  display: inline-block; padding: .1rem .45rem; border-radius: 999px;
  font-size: .75rem; font-weight: 600; background: var(--surface-alt);
  color: var(--text-dim); border: 1px solid var(--border);
}
.pill.open { background: var(--warn-soft); color: var(--text); border-color: var(--warn-border); }
.pill.banned { background: var(--danger-soft); color: var(--danger); border-color: var(--danger); }
.pill.admin { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }

.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin-bottom: 1rem; }
.tabs a { padding: .45rem .75rem; text-decoration: none; color: var(--text-dim);
          border-bottom: 2px solid transparent; font-size: .92rem; }
.tabs a[aria-current="page"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

/* The unread count in the navigation. */
.nav-badge {
  display: inline-block; min-width: 1.15rem; padding: 0 .3rem;
  margin-left: .3rem; border-radius: 999px;
  background: var(--accent); color: var(--accent-text);
  font-size: .7rem; font-weight: 700; text-align: center; line-height: 1.15rem;
}

.quote { border-left: 3px solid var(--border); padding-left: .6rem; color: var(--text-dim); }

.loading { color: var(--text-dim); }

.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;
}

@media (max-width: 30rem) {
  .header-inner { padding: .5rem .75rem; }
  .site-main { padding: 1rem .75rem 2.5rem; }
  .site-nav a { padding: .3rem .45rem; font-size: .85rem; }
}

/* ===========================================================================
   The three-column shell.

   A grid rather than floats or flimsy flex, so the centre column keeps a
   sensible reading width while the rails take whatever is left. `minmax(0, 1fr)`
   on the centre is load-bearing: a plain `1fr` refuses to shrink below its
   content, so one long word in a post would push the right rail off screen.

   Below 64rem the right rail goes first -- it is the least important thing
   here, and on a laptop it is the first thing you would close. Below 48rem
   everything collapses to one column, because a phone has room for a feed and
   nothing else.
   =========================================================================== */

.app-shell {
  display: grid;
  grid-template-columns: 13rem minmax(0, 1fr) 15rem;
  gap: 1.5rem;
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.25rem 1rem 3rem;
  align-items: start;
}

/* One centred column: the sign-in and rules pages, where rails would be
   furniture in an empty room. */
.app-shell.solo {
  grid-template-columns: minmax(0, 1fr);
  max-width: 46rem;
}

/* With one column the rails do not disappear, they stack: the left one lands
   above the content and the right one below it. Empty, and wearing a surface
   of its own, the left rail drew as a white bar floating above the front door
   -- 12.8px of nothing, which reads as a rendering fault because it is one.
   They are furniture in an empty room here, so they are removed rather than
   left to stack. */
.app-shell.solo .rail { display: none; }

.rail { position: sticky; top: 4rem; }

.rail-left a {
  display: block;
  padding: .5rem .65rem;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  text-decoration: none;
  font-weight: 550;
}
.rail-left a:hover { background: var(--surface-alt); color: var(--text); }
.rail-left a[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--accent);
}

.rail-right .card { padding: .85rem; }

/* The main column no longer centres itself: the grid does that now. */
.app-shell .site-main {
  max-width: none;
  margin: 0;
  padding: 0;
}

/* The header's own links are only used while signed out, when there is no
   left rail to hold them. */
.site-header .site-nav { display: flex; }

@media (max-width: 64rem) {
  .app-shell { grid-template-columns: 12rem minmax(0, 1fr); }
  .rail-right { display: none; }
}

@media (max-width: 48rem) {
  .app-shell { grid-template-columns: minmax(0, 1fr); gap: 1rem; padding-top: .75rem; }
  .rail-left {
    position: static;
    display: flex;
    overflow-x: auto;
    gap: .25rem;
    padding-bottom: .25rem;
  }
  .rail-left a { white-space: nowrap; padding: .35rem .55rem; font-size: .9rem; }
}

/* ===========================================================================
   Visual language: clean, modern, Facebook-shaped.

   Everything above this block was drawn without ever seeing it rendered, and
   it shows: a card for every occasion, borders on borders, and one accent
   used at the same intensity everywhere. This block replaces the tokens and
   the surface treatment, which is where most of the impression lives.

   The three changes that matter:

   1. Surfaces float on a grey page rather than sitting in outlined boxes.
      Borders were doing the work that spacing and a soft shadow should do,
      and a screen full of them reads as documentation.

   2. One accent, used sparingly. It marks the current page, the primary
      button, and nothing else. Colour that is everywhere is colour nowhere.

   3. Hierarchy by weight and size, not by boxes. A post body is large and
      dark; a timestamp is small and grey; a section heading is small, grey and
      uppercase. Your eye needs somewhere to land.
   =========================================================================== */

:root {
  /* Taken from the logo: #263434 is the lettering, #563b20 is the table. The
     ground is a warm off-white rather than grey, because a hand-drawn mark on
     a cool grey page looks pasted on. */
  --bg: #faf7f2;
  --surface: #ffffff;
  --surface-alt: #f3efe7;
  --border: #e3ddd3;
  --text: #263434;
  --text-dim: #6d7a78;
  --accent: #563b20;
  --accent-text: #fffdf9;
  --accent-soft: #f2e9dd;
  --danger: #a3382f;
  --danger-soft: #fbeceb;
  --warn-soft: #fdf4e3;
  --warn-border: #e2c98a;
  --ok: #2f6b46;
  --radius: 10px;
  --radius-sm: 7px;
  --max-width: 44rem;
  --shadow: 0 1px 2px rgb(38 52 52 / 7%), 0 4px 14px rgb(38 52 52 / 5%);
  --shadow-lg: 0 2px 16px rgb(38 52 52 / 12%);
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Same two colours, turned up: the brown has to lighten or it disappears
       into the page, and the ground goes warm-dark rather than neutral, so the
       logo does not sit on a different temperature from everything else. */
    --bg: #1b2120;
    --surface: #232b2a;
    --surface-alt: #2d3635;
    --border: #3a4442;
    --text: #e8e6e0;
    --text-dim: #9aa5a2;
    --accent: #c08b5a;
    --accent-text: #201a12;
    --accent-soft: #33291e;
    --danger: #f0a6a0;
    --danger-soft: #3a2523;
    --warn-soft: #3a3320;
    --warn-border: #6d5c2c;
    --ok: #8fd3a8;
    --shadow: 0 1px 2px rgb(0 0 0 / 35%);
    --shadow-lg: 0 2px 16px rgb(0 0 0 / 45%);
  }
}

/* Header appearance is set once, at the foot of this file. */

/* --- surfaces: no outlines, a soft shadow instead ------------------------ */

.card,
.post {
  border: none;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* The feed breathes between posts rather than boxing each one in. */
.post { margin-bottom: .75rem; }
.post-body { padding: 1rem 1rem .65rem; }

.post-author a { font-size: .95rem; }
.post-text { font-size: 1.05rem; line-height: 1.5; margin: .35rem 0 .5rem; }

/* --- the action bar: spaced, quiet, tappable ----------------------------- */

.post-actions {
  border-top: 1px solid var(--border);
  padding: .35rem .5rem;
  gap: .15rem;
}
.post-actions button {
  flex: 1;
  justify-content: center;
  font-weight: 600;
  color: var(--text-dim);
}
.post-actions button:hover:not(:disabled) { background: var(--surface-alt); }

/* --- the rail: a surface, not a list of loose links ---------------------- */

.rail-left {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: .4rem;
}
.rail-left a {
  font-weight: 600;
  font-size: 1rem;
  padding: .55rem .65rem;
  color: var(--text);
}
.rail-left a[aria-current="page"] { background: var(--accent-soft); }

/* --- forms and buttons --------------------------------------------------- */

button.primary, .button.primary {
  border: none;
  font-weight: 600;
  padding: .55rem 1rem;
}
button, .button { border-color: transparent; background: var(--surface-alt); }
button:hover:not(:disabled), .button:hover { background: var(--border); }

input[type="text"], input[type="email"], input[type="password"],
input[type="search"], textarea, select {
  background: var(--surface-alt);
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: .65rem .75rem;
}
input:focus-visible, textarea:focus-visible, select:focus-visible {
  background: var(--surface);
}

/* --- small caps for section labels, which is what gives a page structure -- */

.card h2 { font-size: 1.05rem; }
.rail-right .card p.tiny,
.card > p.tiny:first-child { letter-spacing: .04em; text-transform: uppercase; }

.tabs { border-bottom: 1px solid var(--border); }
.tabs a { font-weight: 600; }
.tabs a[aria-current="page"] { border-bottom-color: var(--accent); }


/* --- header, take three --------------------------------------------------
   Three complaints, one cause each:

   1. The logo could not be seen. It was 2.75rem tall for a mark that carries
      two lines of hand-lettering; it is 3.5rem now.

   2. It was not left aligned. The header was still constrained to the old
      44rem column and centred, while the shell below it is 76rem -- so the
      logo floated somewhere near the middle, out of line with the rail. Both
      now share a width and the same 1rem gutter, which is what lines them up.

   3. No border. Removed, along with the shadow. The header is white and the
      page is warm off-white, so the colour already separates them; the hard
      line was doing a job that no longer needed doing.
   ------------------------------------------------------------------------ */

.site-header {
  border-bottom: none;
  box-shadow: none;
}
.header-inner {
  max-width: 76rem;
  padding: .6rem 1rem;
  align-items: center;
}
/* Two lines of hand-lettering need real height. At 2.75rem the 'church' line
   was about ten pixels and read as a smudge. */
.brand-logo { height: 4.5rem; width: auto; display: block; }
.brand picture { display: block; }
.brand:hover .brand-logo { opacity: .85; }

@media (max-width: 48rem) {
  .header-inner { max-width: none; }
  .brand-logo { height: 3.25rem; }
}

/* --- footer --------------------------------------------------------------
   No top border, for the same reason the header has none: the page ground and
   the footer's own spacing separate it, and a rule across the width was the
   one hard line left in a design that has stopped using them.
   ------------------------------------------------------------------------ */

.site-footer {
  max-width: 76rem;
  margin: 0 auto;
  padding: 2rem 1rem 3rem;
  color: var(--text-dim);
  font-size: .85rem;
}
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-bottom: .75rem;
}
.footer-links a {
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}
.footer-links a:hover { color: var(--accent); text-decoration: underline; }
.footer-links a[aria-current="page"] { color: var(--accent); }

/* --- reactions ----------------------------------------------------------- */

/* The picker floats over the card rather than pushing the layout around, so
   opening it does not make the feed jump. */
.reaction-panel {
  display: flex;
  gap: .15rem;
  width: fit-content;
  margin: 0 .75rem .5rem;
  padding: .3rem .4rem;
  background: var(--surface-alt);
  border-radius: 999px;
  box-shadow: var(--shadow);
}
.reaction-panel[hidden] { display: none; }
.reaction-panel button {
  font-size: 1.2rem;
  line-height: 1;
  padding: .3rem .45rem;
  border-radius: 999px;
  background: none;
  transition: transform .1s ease;
}
.reaction-panel button:hover { transform: scale(1.2); background: none; }

/* --- threaded comments ---------------------------------------------------
   Indentation is the only difference between a comment and a reply: same
   markup, same type, one margin. Past three levels the database refuses, so
   there is no case where this needs to keep stepping in.
   ------------------------------------------------------------------------ */

.replies { margin-left: 1.25rem; padding-left: .75rem; border-left: 2px solid var(--border); }
.comment { padding: .5rem 0; }
.comment + .comment { border-top: 1px solid var(--border); }
.comment .row-tight { gap: .5rem; margin-top: .2rem; }

/* A named member is underlined rather than coloured: the accent is used for
   state (which tab you are on, whether you have already liked this), and a
   link in the middle of a sentence is not state. */
.mention {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: var(--accent);
}
.mention:hover { color: var(--accent); }

/* --- a post carrying another post ----------------------------------------
   Inset rather than full-bleed, so it reads as something quoted inside the
   sharer's post rather than as a second post underneath it. A left rule does
   the same job as the one on a reply thread, which is the point: both mean
   "this came from somewhere else".
   ------------------------------------------------------------------------ */

.shared-post {
  margin: .5rem 0 .25rem;
  padding: .6rem .75rem .75rem;
  border-left: 3px solid var(--border);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-alt);
}
.shared-post .post-author { margin-bottom: .25rem; }
.shared-post .post-text { font-size: 1rem; margin: 0 0 .25rem; }
.shared-post .post-images { margin-top: .5rem; }

/* --- sponsored cards ------------------------------------------------------
   Deliberately NOT a .post: different shape, different colour, a rule along
   the top and a label. An advert that could pass for a post would be the one
   genuinely dishonest thing on this site.
   ------------------------------------------------------------------------ */

.ad-card {
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: var(--surface);
  border-top: 3px solid var(--accent);
  margin-bottom: .75rem;
  overflow: hidden;
}
.ad-label {
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: .5rem .9rem 0;
}
.ad-body { display: flex; gap: .9rem; padding: .35rem .9rem .9rem; align-items: flex-start; }
.ad-image {
  width: 6rem;
  height: 6rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex: none;
}

/* --- groups and events ----------------------------------------------------
   Both are cards in a list, and both need the same two things a card needs
   here: a heading that sits on one line with its badge, and a row of quiet
   controls at the bottom. Nothing new is invented for them.
   ------------------------------------------------------------------------ */

.group-card h3,
.event-card h3 { font-size: 1.05rem; }
.event-card.past { opacity: .68; }
.event-card input[type="text"],
.event-card input[type="datetime-local"],
.event-card textarea { margin-bottom: .5rem; }
/* A past event keeps its RSVP buttons rather than losing them: people do
   change their mind about whether they went, and the count should follow. */

/* --- pages ----------------------------------------------------------------
   A directory card is a link, so it must not look like a link: no underline,
   and the heading is what carries the colour on hover.
   ------------------------------------------------------------------------ */

.page-card { text-decoration: none; color: inherit; display: block; }
.page-card:hover h3 { color: var(--accent); }

/* --- private conversations ------------------------------------------------
   Bubbles rather than a card per message: a conversation is one object, and
   boxing each line makes two people talking look like two people posting at
   each other. Yours are right-aligned and the accent colour; theirs are not.
   ------------------------------------------------------------------------- */

.dm-thread { display: flex; flex-direction: column; }
.dm-log {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .35rem .25rem 1rem;
  /* Tall enough to read a conversation, capped so one long thread does not
     push the composer off the bottom of a phone. */
  max-height: 60vh;
  overflow-y: auto;
}
.dm-bubble {
  max-width: 78%;
  padding: .45rem .7rem .3rem;
  border-radius: var(--radius);
  background: var(--surface-alt);
  align-self: flex-start;
}
.dm-bubble.mine {
  align-self: flex-end;
  background: var(--accent-soft);
}
.dm-body { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.45; }
.dm-bubble .tiny { text-align: right; }
.dm-compose {
  display: flex;
  gap: .5rem;
  align-items: flex-end;
  border-top: 1px solid var(--border);
  padding-top: .75rem;
}
.dm-compose textarea { min-height: 2.8rem; flex: 1; }

.dm-row { text-decoration: none; color: inherit; }
.dm-row .ellipsis {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- the profile header ---------------------------------------------------
   The card clips its own corners so the cover does not need a radius of its
   own, and the avatar is pulled up over the bottom edge of the picture so the
   two read as one object rather than two stacked ones. Negative margin only
   when there IS a cover: without it, the avatar would ride up into the card's
   padding and the name would sit too high.
   ------------------------------------------------------------------------ */

.profile-header { overflow: hidden; }
.profile-cover {
  display: block;
  width: calc(100% + 2rem);
  /* Pulled out past the card's horizontal padding, so the strip reaches both
     edges instead of floating inside a margin. */
  margin: -1rem -1rem .75rem;
  height: 10rem;
  object-fit: cover;
}
/* The avatar does NOT overlap the cover, and it was tried twice.

   Overlapping is what Facebook does and it looks better when it works. It
   does not work here, for a boring reason: the header row is a flex row whose
   height is set by the tallest item, so lifting the row by a fixed amount
   moves the NAME onto the photograph too -- and how far the name overlaps
   depends on how many lines of it there are, which the stylesheet cannot
   know. Both attempts produced a display name sitting on a dark hillside,
   which is exactly the legibility problem this whole page exists to avoid.

   Doing it properly means giving the avatar its own row or an absolutely
   positioned wrapper. That is a layout change for one decorative overlap, and
   a legible name is worth more than the overlap. */
.profile-cover + .row { margin-top: .75rem; }

/* --- the front door ------------------------------------------------------
   Two columns of reasons on a wide screen, one on a narrow one, so the page
   reads as an argument rather than a list of paragraphs.
   ------------------------------------------------------------------------ */

.welcome-logo { height: 4.5rem; width: auto; }
.welcome-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: .85rem;
  margin-bottom: .85rem;
}
.welcome-grid .card { margin: 0; }
.welcome-grid h2 { margin-bottom: .35rem; }
@media (max-width: 48rem) { .welcome-logo { height: 3.25rem; } }
