/* Shared chrome + server-page components, on the parchment design system.
   Tokens come from tokens-parchment.css (loaded first, at :root, on every page
   via head.php). Per-page stylesheets (landing-intro.css, creation.css,
   home.css) load after this and layer on top. */

*{box-sizing:border-box;margin:0;padding:0}

html,body{
  background:var(--surface-page);color:var(--text-body);
  font-family:var(--font-ui);min-height:100vh;overflow-x:hidden;
}

/* A link's default colour. The app had none, so any anchor nobody had styled by
   hand — the journal's "Write one", for instance — came out in the browser's
   #0000EE on parchment. The design system's base has carried this rule all
   along; the app just never picked it up. */
a{color:var(--text-action)}
a:hover{color:var(--accent-primary)}
/* The wordmark is insignia, not a link that changes colour under the pointer.
   The generic a:hover above out-specifies .nav-logo, so it needs saying. */
.nav-logo:hover{color:var(--text-accent)}

/* NAV */
.site-nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  padding:0 2.5rem;height:var(--nav-height);
  background:rgba(253,248,236,0.85);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--border-hairline);
}
.nav-logo{flex:0 1 auto;min-width:0;font-family:var(--font-display);font-size:var(--fs-sm);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-accent);text-decoration:none}
.nav-links{display:flex;gap:2rem;list-style:none;align-items:center}
.nav-links a{font-family:var(--font-ui);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted);text-decoration:none;transition:color var(--dur-base) var(--ease-standard)}
.nav-links a:hover,.nav-links a.active{color:var(--text-accent)}
.nav-user{font-family:var(--font-ui);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted)}
.nav-logout{background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted);transition:color var(--dur-base) var(--ease-standard)}
.nav-logout:hover{color:var(--text-accent)}
.nav-cta{
  font-family:var(--font-ui);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;
  background:var(--accent-primary);color:var(--text-on-accent);border:1px solid var(--accent-primary);border-radius:var(--radius-sm);
  padding:7px 18px;text-decoration:none;transition:background var(--dur-base) var(--ease-standard),border-color var(--dur-base) var(--ease-standard);
}
.nav-cta:hover{background:var(--accent-primary-hover);border-color:var(--accent-primary-hover)}
.nav-actions{display:flex;align-items:center;gap:1.4rem}
.nav-actions a:not(.nav-cta){font-family:var(--font-ui);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted);text-decoration:none;transition:color var(--dur-base) var(--ease-standard)}
.nav-actions a:not(.nav-cta):hover{color:var(--text-accent)}

/* PAGE SHELL */
main{max-width:var(--width-content);margin:0 auto;padding:calc(var(--nav-height) + var(--space-11)) var(--gutter-page) var(--space-12)}
.page-header{text-align:center;margin-bottom:var(--space-9)}
.page-header h1{font-family:var(--font-display);font-size:var(--fs-2xl);font-weight:500;color:var(--text-strong);letter-spacing:var(--track-title);margin-bottom:var(--space-3)}
.page-header p{font-family:var(--font-prose);font-size:var(--fs-md);font-style:italic;color:var(--text-muted)}

/* AUTH / INFO CARD */
/* Frame comes from .ag-panel in components.css; this is the auth card's own
   measure and elevation. */
.auth-card{
  box-shadow:var(--shadow-sm);padding:var(--space-9) var(--space-8);max-width:420px;margin:0 auto;
}
.auth-card h1{font-family:var(--font-display);font-size:var(--fs-lg);letter-spacing:var(--track-title);color:var(--text-strong);margin-bottom:var(--space-8);text-align:center}

/* FORMS */
.field{margin-bottom:var(--space-6)}
.field label{display:block;font-family:var(--font-display);font-size:var(--fs-2xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted);margin-bottom:var(--space-2)}
.field input{
  width:100%;font-family:var(--font-ui);font-size:var(--fs-md);color:var(--text-strong);
  background:var(--surface-inset);border:1px solid var(--border-default);border-radius:var(--radius-sm);
  padding:10px 12px;outline:none;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);
}
.field input:focus{border-color:var(--accent-primary);box-shadow:var(--focus-ring)}
/* Not scoped to .field — guilds.php and account.php use it standalone too. */
.hint{font-family:var(--font-prose);font-size:var(--fs-xs);color:var(--text-muted);font-style:italic;margin-top:var(--space-2)}
.field>div{color:var(--text-body);font-size:var(--fs-md)}
.form-actions{margin-top:var(--space-8);display:flex;flex-direction:column;gap:var(--space-5);align-items:stretch}
.form-actions .btn-primary{text-align:center}
.form-alt{text-align:center;font-family:var(--font-ui);font-size:var(--fs-sm);color:var(--text-muted);margin-top:var(--space-6)}
.form-alt a{color:var(--text-action);text-decoration:none}
.form-alt a:hover{text-decoration:underline}

/* The login card's own furniture. The crest replaces the wordmark as the thing
   at the top of the screen: to someone already trying to get back in, the brand
   is not news, but the mark is a landmark. */
.auth-crest{display:flex;justify-content:center;color:var(--text-accent);margin-bottom:var(--space-5)}
/* Login frames the form, not the whole screen: the crest, the heading and the
   three lines under the button sit on the page itself, so the outer card gives
   up its surface and keeps only its measure. */
.auth-card--login{background:transparent;border:0;box-shadow:none;padding:0}
.auth-form-card{padding:var(--space-7) var(--space-6);box-shadow:var(--shadow-sm)}

/* Password + its reveal button on one line. The button is appended by
   login.js, so this rule has to hold for a row of one child as well as two. */
.field-reveal{display:flex;gap:var(--space-4);align-items:stretch}
.field-reveal input{flex:1 1 auto;min-width:0}
.field-reveal-btn{
  flex:0 0 auto;padding:0 var(--space-6);cursor:pointer;
  font-family:var(--font-ui);font-size:var(--fs-xs);font-weight:600;color:var(--text-body);
  background:transparent;border:1px solid var(--border-default);border-radius:var(--radius-sm);
  transition:border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);
}
.field-reveal-btn:hover{border-color:var(--accent-primary);color:var(--text-accent)}
.field-reveal-btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}

/* A checkbox that reads as one target: the box and its words are one label, so
   the whole line is tappable rather than just the eight pixels of the box. */
.field-check{
  display:flex;align-items:center;gap:var(--space-5);
  min-height:44px;cursor:pointer;
  font-family:var(--font-ui);font-size:var(--fs-sm);color:var(--text-body);
}
.field-check input{width:18px;height:18px;flex:0 0 auto;accent-color:var(--accent-primary);cursor:pointer}

.form-note{text-align:center;font-family:var(--font-ui);font-size:var(--fs-xs);line-height:1.55;color:var(--text-faint);margin-top:var(--space-5)}
.form-flavour{text-align:center;font:var(--type-flavour);font-size:var(--fs-sm);color:var(--text-faint);margin-top:var(--space-6)}

/* BANNERS */
.banner{border-radius:var(--radius-sm);padding:10px 14px;margin-bottom:var(--space-6);font-family:var(--font-ui);font-size:var(--fs-sm);line-height:1.5}
.banner-error{background:var(--status-error-bg);border:1px solid var(--status-error-border);color:var(--status-error-text)}
.banner-ok{background:var(--status-ok-bg);border:1px solid var(--status-ok-border);color:var(--status-ok-text)}
/* The third note. Neither a failure nor a success — a standing fact about the
   account, which is what the unconfirmed-address nag is reporting. There is no
   --status-info triad to pair with the other two, so it borrows the quiet gold
   surface the design system already uses for asides. */
.banner-note{background:var(--surface-gold-quiet);border:1px solid var(--border-default);color:var(--text-body)}
.banner-note a{color:var(--text-action)}
.banner ul{margin:0;padding-left:1.1rem}

/* SIMPLE LISTS (guilds page) */
.card-list{list-style:none;display:flex;flex-direction:column;gap:var(--space-4);margin:var(--space-8) 0}
.card-list li{background:var(--surface-card);border:1px solid var(--border-hairline);border-radius:var(--radius-md);padding:var(--space-6) var(--space-7);display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-6)}
.card-list .guild-name{font-family:var(--font-display);font-size:var(--fs-sm);letter-spacing:var(--track-title);color:var(--text-strong)}
.card-list .guild-meta{font-family:var(--font-ui);font-size:var(--fs-sm);color:var(--text-muted)}
.card-list code,code{font-family:var(--font-display);letter-spacing:0.15em;color:var(--text-accent);background:var(--surface-sunken);padding:2px 8px;border-radius:var(--radius-xs)}
.stack-forms{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-8);margin-top:var(--space-11)}
.stack-forms .auth-card{margin:0;max-width:none}
.empty-note{font-family:var(--font-prose);font-style:italic;color:var(--text-muted);text-align:center;margin:var(--space-8) 0}

/* XP / CHARACTER VIEW (account.php) */
.auth-card + .auth-card{margin-top:var(--space-8)}
.section-label-row{font-family:var(--font-display);font-size:var(--fs-2xs);font-weight:600;letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-accent);margin:var(--space-8) 0 var(--space-4)}
.xp-main{display:flex;align-items:center;gap:var(--space-7)}
.xp-level{display:flex;flex-direction:column;align-items:center;flex-shrink:0;min-width:74px;padding:var(--space-4) var(--space-5);border:1px solid var(--border-hairline);border-radius:var(--radius-md);background:var(--surface-raised)}
.xp-level-word{font-family:var(--font-display);font-size:var(--fs-3xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted)}
.xp-level-num{font-family:var(--font-display);font-size:var(--fs-3xl);line-height:1.05;color:var(--text-strong)}
.xp-main-meter{flex:1;min-width:0}
.xp-main-meta{display:flex;justify-content:space-between;gap:var(--space-4);margin-top:var(--space-3);font-family:var(--font-ui);font-size:var(--fs-xs);color:var(--text-muted)}
/* .ag-meter: the pill shape, the overflow clip and the --fill-meter gradient
   all come from components.css. The height and the ground are the account
   page's own. */
.xp-bar{height:6px;background:var(--surface-sunken)}
.xp-track-list{list-style:none;display:flex;flex-direction:column;gap:var(--space-4)}
.xp-track-list li{display:grid;grid-template-columns:minmax(90px,1fr) 2fr minmax(120px,auto);align-items:center;gap:var(--space-5)}
.xp-track-name{font-family:var(--font-display);font-size:var(--fs-sm);color:var(--text-strong);text-transform:capitalize}
.xp-track-meta{font-family:var(--font-ui);font-size:var(--fs-xs);color:var(--text-muted);text-align:right}

/* XP SANDBOX (only rendered when APP_XP_DEBUG is on) */
.xp-sandbox{max-width:720px}
.xp-quick{display:flex;flex-wrap:wrap;gap:var(--space-4)}
.xp-quick .btn-secondary{font-size:var(--fs-sm);padding:8px 14px}
.xp-ledger{list-style:none;display:flex;flex-direction:column;gap:var(--space-2);font-family:var(--font-ui);font-size:var(--fs-xs)}
.xp-ledger li{display:flex;flex-wrap:wrap;gap:var(--space-5);align-items:baseline;padding:var(--space-3) var(--space-4);background:var(--surface-raised);border:1px solid var(--border-hairline);border-radius:var(--radius-xs)}
.xp-ledger-amt{font-family:var(--font-display);color:var(--text-strong);min-width:52px}
.xp-ledger-src{color:var(--text-accent)}
.xp-ledger-trk,.xp-ledger-main{color:var(--text-muted)}
.xp-ledger-at{margin-left:auto;color:var(--text-muted)}

/* FOOTER */
footer{
  padding:2.5rem;display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;gap:1rem;border-top:1px solid var(--border-hairline);
}
.footer-logo{font-family:var(--font-display);font-size:var(--fs-xs);letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted)}
.footer-copy{font-family:var(--font-prose);font-size:var(--fs-sm);color:var(--text-muted);font-style:italic}

/* The nav is a fixed-height flex row, and flex items will not shrink below
   their text, so past four links the actions column starts overlapping the
   links. Tighten the gaps first, then drop the display name — it is a nicety,
   not navigation — before anything can collide. */
@media(max-width:1080px){
  .site-nav{padding:0 1.5rem}
  .nav-links{gap:1.25rem}
  .nav-actions{gap:1rem}
}
@media(max-width:768px){
  .nav-user{display:none}
}

@media(max-width:560px){
  .site-nav{padding:0 var(--gutter-page)}
  .nav-links{display:none}
  main{padding-top:calc(var(--nav-height) + var(--space-8))}
  .stack-forms{grid-template-columns:1fr}
  footer{flex-direction:column;align-items:flex-start}
  .xp-track-list li{grid-template-columns:1fr;gap:var(--space-2)}
  .xp-track-meta{text-align:left}
  .xp-ledger-at{margin-left:0}

  /* THE AUTH CARD ON A PHONE
     The card stops being an object floating in a page and becomes the page.
     Inputs go to 48px: 44 is the tap-target floor, and the extra 4 buys the
     reveal button a matching height without it looking bolted on. The 16px
     font is not a style choice — iOS zooms the viewport on focusing any input
     below 16px, and the zoom does not come back. */
  .auth-card{padding:var(--space-8) var(--space-7);max-width:none;box-shadow:var(--shadow-xs)}
  .auth-card--login h1{font-size:var(--fs-xl)}
  .field label{font-size:var(--fs-3xs);color:var(--text-accent)}
  .field input{min-height:48px;font-size:16px;padding:12px}
  .field-reveal-btn{min-height:48px}
  .form-actions .btn-primary{min-height:52px;font-size:var(--fs-md)}
}

/* ==========================================================================
   THE MOBILE SHELL
   Below sm, the desktop nav is not narrowed — it is replaced. Until now the
   links were simply hidden here, which left a phone with no way at all to reach
   Guilds, the Journal or Quests: you could get to the logo and to Log out.

   The design's answer, and this one: identity in the top-left where the wordmark
   sits on desktop, a drawer for everything occasional, and a fixed bottom bar
   carrying the three places you actually go. Every target is at least 44px.
   ========================================================================== */

.nav-me, .nav-account, .tabbar { display: none; }

@media(max-width:560px){
  .site-nav{
    height:var(--nav-height-mobile);padding:0 var(--space-4) 0 var(--gutter-page);
    flex-wrap:nowrap;align-items:center;gap:var(--space-4);
  }
  /* Hidden only when the mobile shell is actually there to replace them. The
     shell renders for a logged-in user; a visitor still needs the wordmark, Log
     in and Sign Up, and hiding those left them with an empty bar and no way in. */
  .nav-links{ display:none }
  .has-mobile-shell .nav-logo,
  .has-mobile-shell .nav-actions{ display:none }
  /* Logged out, the bar is just the wordmark and the two ways in. */
  .site-nav:not(.has-mobile-shell){ flex-wrap:nowrap;gap:var(--space-5) }
  .site-nav:not(.has-mobile-shell) .nav-logo{
    flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .site-nav:not(.has-mobile-shell) .nav-actions{ flex:0 0 auto;gap:var(--space-5) }

  /* Identity: who you are and how far along, in one tap-target to your account. */
  .nav-me{
    display:flex;align-items:center;gap:var(--space-5);
    min-height:44px;flex:1 1 auto;min-width:0;text-decoration:none;
  }
  .nav-me-crest{
    flex:0 0 auto;width:28px;height:28px;border-radius:var(--radius-pill);
    display:inline-flex;align-items:center;justify-content:center;
    border:1px solid var(--gold-700);background:var(--surface-gold-quiet);
    font-family:var(--font-display);font-size:var(--fs-2xs);color:var(--text-accent);
  }
  .nav-me-text{ display:flex;flex-direction:column;min-width:0 }
  .nav-me-name{
    font-family:var(--font-display);font-size:var(--fs-sm);
    letter-spacing:var(--track-title);color:var(--text-strong);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .nav-me-meta{
    font-size:var(--fs-3xs);letter-spacing:var(--track-label);
    text-transform:uppercase;color:var(--text-muted);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }

  /* Where More used to be: a square the size of a thumb, with the person mark
     the designs use for the account everywhere it appears. A link, not a
     button — it goes somewhere rather than opening something. */
  .nav-account{
    display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
    width:44px;height:44px;
    border:1px solid var(--border-rule);border-radius:var(--radius-sm);
    background:transparent;color:var(--text-body);text-decoration:none;
  }
  .nav-account:hover{ border-color:var(--accent-primary);color:var(--text-accent) }
  .nav-account:focus-visible{ outline:none;box-shadow:var(--focus-ring) }

  /* The bottom bar. Plain links, so navigation survives with JS switched off —
     which the drawer does not, and does not need to. */
  .tabbar{
    display:flex;position:fixed;bottom:0;left:0;right:0;z-index:100;
    justify-content:center;
    background:rgba(253,248,236,0.94);backdrop-filter:blur(12px);
    border-top:1px solid var(--border-hairline);
    padding-bottom:env(safe-area-inset-bottom,0);
  }
  .tabbar a{
    flex:1 1 0;max-width:calc(440px / 3);min-height:58px;
    display:flex;flex-direction:column;gap:var(--space-1);
    align-items:center;justify-content:center;
    font-family:var(--font-ui);font-size:var(--fs-3xs);font-weight:600;
    letter-spacing:var(--track-label);
    color:var(--text-muted);text-decoration:none;
  }
  /* The icon takes the link's colour, so the active state needs no second rule. */
  .tabbar-icon{ display:block;flex:0 0 auto }
  .tabbar a.is-on{
    font-weight:700;color:var(--accent-primary);
    box-shadow:inset 0 2px 0 var(--accent-primary);
  }

  /* Clear the bar. Without this the last row of every page sits under it, and
     on the journal that row is a tick you cannot reach. */
  main{ padding-top:calc(var(--nav-height-mobile) + var(--space-8)) }
  /* Only the footer needs to clear the bar — it is what comes last. Padding main
     as well just left a hole above it. */
  footer{ padding-bottom:calc(58px + var(--space-8) + env(safe-area-inset-bottom,0)) }
}

/* ==========================================================================
   THE DESKTOP RAIL

   From App Rail.dc.html: a 244px sticky column carrying the whole of navigation,
   with no top bar above the page at all. lib/partials/nav.php wraps the page in
   .ag-shell and lib/partials/footer.php closes it, so the rail and the page are
   flex siblings.

   The markup renders at every width; only this block turns it on. Below 1080px
   the rail is hidden and the top bar and the tab bar are exactly as they were —
   see docs/app-rail-plan.md on why there are three shells rather than two, and
   why 1080 rather than a fourth breakpoint: 244 + --width-content is 1104, so the
   rail and the existing page measure fit side by side at almost precisely the
   documented lg step.

   1080 is also the top of the max-width:1080px band that tightens the top bar.
   Both blocks match at exactly 1080px and it does not matter: this one hides the
   bar the other one is adjusting.
   ========================================================================== */

.app-rail{ display:none }

@media(min-width:1080px){
  .ag-shell{ min-height:100vh }
  .ag-shell-body{ min-width:0;margin-left:244px;display:flex;flex-direction:column;min-height:100vh }

  /* The rail replaces both of the other shells rather than sitting alongside
     either. The tab bar is already display:none this wide; the top bar is not.
     Scoped to .has-rail, which head.php only sets where there is a rail to
     replace it — a logged-out visitor and the two opted-out screens keep the bar
     at every width, and hiding it for them left the landing page with no chrome
     at all. */
  .has-rail .site-nav{ display:none }

  /* FIXED, not the design's position:sticky, and the difference is not cosmetic.
     html and body both carry overflow-x:hidden, and overflow on body does not
     propagate to the viewport the way html's does — so body becomes the scroll
     container, the viewport does the scrolling, and a sticky child of body has no
     scrollport to stick inside. It renders exactly like position:static and the
     rail scrolls off the top of the screen. (An e2e case holds this: "the rail
     follows you down a long page".)

     Fixed behaves identically to what the design draws and depends on nothing.
     overflow-y:auto so a short window can still reach the bottom of the list, and
     .ag-shell-body carries the 244px the rail no longer occupies. */
  .app-rail{
    display:flex;flex-direction:column;gap:var(--space-7);
    position:fixed;top:0;left:0;width:244px;height:100vh;overflow-y:auto;
    padding:var(--space-7) var(--space-6);
    background:var(--surface-card);border-right:1px solid var(--border-hairline);
    color:var(--text-strong);
  }

  /* The wordmark, as insignia rather than a link that changes colour under the
     pointer — the same rule .nav-logo gets, for the same reason. */
  .rail-mark{
    padding:0 var(--space-4);
    font-family:var(--font-display);font-size:var(--fs-2xs);font-weight:600;
    letter-spacing:0.18em;text-transform:uppercase;
    color:var(--text-accent);text-decoration:none;
  }
  .rail-mark:hover{ color:var(--text-accent) }

  /* Who you are and how far along, in a card that goes to your character sheet.
     The same three facts as the mobile identity strip, off the same query. */
  .rail-me{
    display:flex;gap:var(--space-5);align-items:center;
    padding:var(--space-5);text-decoration:none;
    border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
    transition:border-color var(--dur-base) var(--ease-standard);
  }
  .rail-me:hover{ border-color:var(--gold-700) }
  .rail-me-crest{
    flex:0 0 auto;width:32px;height:32px;border-radius:var(--radius-pill);
    display:inline-flex;align-items:center;justify-content:center;
    border:1px solid var(--gold-700);background:var(--surface-gold-quiet);
    font-family:var(--font-display);font-size:var(--fs-sm);color:var(--text-accent);
  }
  .rail-me-text{ display:flex;flex-direction:column;min-width:0 }
  .rail-me-name{
    font-family:var(--font-display);font-size:var(--fs-sm);
    letter-spacing:var(--track-title);color:var(--text-strong);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .rail-me-meta{
    font-size:var(--fs-3xs);letter-spacing:var(--track-label);
    text-transform:uppercase;color:var(--text-muted);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }

  .rail-primary,.rail-more{ display:flex;flex-direction:column;gap:var(--space-1) }
  .rail-primary a{
    display:flex;gap:var(--space-5);align-items:center;min-height:40px;
    padding:0 var(--space-5);text-decoration:none;border-radius:var(--radius-sm);
    font-size:var(--fs-sm);font-weight:600;color:var(--text-body);
  }
  /* Gold on a quiet gold wash, with a bar down the leading edge. An inset shadow
     rather than a border-left, so the row does not shift 2px when it becomes
     current. */
  .rail-primary a.is-on{
    font-weight:700;color:var(--text-accent);background:var(--surface-gold-quiet);
    box-shadow:inset 2px 0 0 var(--accent-primary);
  }
  .rail-primary a:hover{ color:var(--text-accent) }
  .rail-icon{ display:block;flex:0 0 auto }

  .rail-more{ padding-top:var(--space-6);border-top:1px solid var(--border-hairline) }
  .rail-more-label{
    margin:0 0 var(--space-3);padding:0 var(--space-5);
    font-family:var(--font-display);font-size:var(--fs-3xs);
    letter-spacing:var(--track-label);text-transform:uppercase;color:var(--text-muted);
  }
  /* The rows here and the logout button have to be one another's twins — the
     button is only a button because logout.php refuses a GET, and it would be a
     poor reason for it to look different. */
  .rail-more a,.rail-logout button{
    display:block;width:100%;text-align:left;
    line-height:36px;white-space:nowrap;padding:0 var(--space-5);
    background:none;border:0;cursor:pointer;
    font-family:var(--font-ui);font-size:var(--fs-sm);font-weight:400;
    color:var(--text-body);text-decoration:none;border-radius:var(--radius-sm);
  }
  .rail-more a:hover,.rail-logout button:hover{ color:var(--text-accent) }
  .rail-more a.is-on{
    font-weight:600;color:var(--text-accent);background:var(--surface-gold-quiet);
  }

  .rail-flavour{
    margin:auto 0 0;padding:0 var(--space-5);
    font-family:var(--font-prose);font-style:italic;font-size:var(--fs-xs);
    color:var(--text-faint);text-wrap:pretty;
  }

  /* The page beside the rail. Nothing is fixed above it any more, so the top
     padding that used to clear the nav bar becomes ordinary breathing room. */
  /* Nothing is fixed above the page any more, so the top padding that used to
     clear the nav bar becomes ordinary breathing room. main grows to fill the
     column so the footer sits at the bottom of the screen rather than stranded
     halfway down beside a full-height rail. */
  .ag-shell-body main{ flex:1 1 auto;padding-top:var(--space-9) }
  /* The in-page back links stay. account.php's is already hidden above 560px,
     and quest.php's goes to /quests.php?view=find — the board, which is not
     where the rail's Quests row lands. Hiding it would lose a destination. */
}

/* ===========================================================================
   WHEN THE CREST IS STRUCK

   The journal sends XP to the crest in the top-left, and a level up changes the
   line underneath it. Both live here rather than in journal.css because these
   are nav elements and the nav owns them — but the journal is the only thing
   that currently makes them move.

   There are two identities in the markup and at most one on screen: the mobile
   strip below 560px, the rail's adventurer card at 1080px and up. Both wear
   these classes. In the band between, neither has a box, and
   assets/js/journal.js checks for one before aiming anything at it — falling
   back to letting the XP rise off the row instead.
   ========================================================================== */

@keyframes ag-struck {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0 rgba(184,134,11,0); }
  40%  { transform: scale(1.18); box-shadow: 0 0 0 5px rgba(184,134,11,0.22); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0 rgba(184,134,11,0); }
}
.nav-me-crest.is-struck,
.rail-me-crest.is-struck {
  animation: ag-struck 620ms var(--ease-out);
  border-color: var(--gold-500);
}

/* A level up is the one thing on this bar worth interrupting for, and here it is
   still only a line of text changing. That is now deliberate rather than pending:
   the real ceremony exists (assets/css/ceremony.css) and answers a whole month of
   catching up. This is what a single tick gets, because a single tick is not a
   month, and a card that rose for every one of them would stop meaning anything. */
@keyframes ag-risen {
  0%   { opacity: 1;   letter-spacing: var(--track-label); }
  25%  { opacity: 0.2; }
  60%  { opacity: 1;   letter-spacing: 0.22em; color: var(--text-accent); }
  100% { opacity: 1;   letter-spacing: var(--track-label); }
}
.nav-me-meta.is-risen,
.rail-me-meta.is-risen { animation: ag-risen 1400ms var(--ease-standard); }

@media (prefers-reduced-motion: reduce) {
  .nav-me-crest.is-struck, .nav-me-meta.is-risen,
  .rail-me-crest.is-struck, .rail-me-meta.is-risen { animation: none; }
}

/* ==========================================================================
   THE UNCONFIRMED-ADDRESS NAG

   Rendered by lib/partials/nav.php for any logged-in person whose address is not
   confirmed, so it appears once per page and no page has to know about it.

   It sits BEFORE <main> in the flow, and <main> is what clears the fixed top bar
   (padding-top: nav-height + …). So the wrapper takes that clearance over and
   <main> gives it up while the nag is there — hence the adjacent-sibling rule,
   which is also why this block lives at the END of the file: it has to win against
   `.ag-shell-body main` on source order, the two being of equal specificity.

   Above 1080px there is no top bar to clear. The rail is the chrome, and
   `.ag-shell-body main` already drops its own clearance for that reason.
   ========================================================================== */

.verify-nag-wrap{
  max-width:var(--width-content);margin:0 auto;
  padding:calc(var(--nav-height) + var(--space-11)) var(--gutter-page) 0;
}
.verify-nag-wrap + main{ padding-top:var(--space-6) }

.verify-nag{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--space-2) var(--space-6);
}
.verify-nag a{ white-space:nowrap;font-family:var(--font-ui);font-weight:600 }

/* The mobile bar is shorter, and so is the breathing room — matching what main's
   own padding does at this width. */
@media(max-width:560px){
  .verify-nag-wrap{ padding-top:calc(var(--nav-height-mobile) + var(--space-8)) }
}

@media(min-width:1080px){
  .verify-nag-wrap{ padding-top:var(--space-9) }
}
