/* physicalaccess.net -- no external resources, so it satisfies the strict CSP
   Caddy sends (default-src 'self'). No fonts, no CDNs, no trackers. */
:root {
  color-scheme:light;
  --bg:#fbfbfa; --fg:#1a1a18; --mut:#63635d; --line:#e3e3de;
  --accent:#7a4b2a; --code:#f2f2ee;
  --max:44rem;
}
/* Three states. Bare :root is the light palette. The media query is GUARDED with
   :not([data-theme="light"]) so that choosing light on a dark-mode OS is honoured,
   and the explicit [data-theme="dark"] rule lets the switch win in both
   directions. color-scheme keeps scrollbars and form controls in step. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#16161a; --fg:#e9e9e4; --mut:#9b9b93; --line:#2b2b31;
    --accent:#d4a373; --code:#1e1e24; color-scheme:dark;
  }
}
:root[data-theme="dark"] {
  --bg:#16161a; --fg:#e9e9e4; --mut:#9b9b93; --line:#2b2b31;
  --accent:#d4a373; --code:#1e1e24; color-scheme:dark;
}
:root[data-theme="light"] { color-scheme:light; }

/* --- theme switch --------------------------------------------------------- */
/* margin-left:auto parks it at the end of the nav flex row. It is injected by
   theme.js, so it simply never appears if scripting is off -- the system
   preference still applies, which is the sensible fallback. */
.theme-toggle {
  margin-left:auto; background:none; border:0; padding:0; cursor:pointer;
  color:var(--mut); line-height:0; display:inline-flex; align-items:center;
  align-self:center;
}
.theme-toggle:hover { color:var(--accent); }
.theme-toggle:focus-visible { outline:2px solid var(--accent); outline-offset:4px;
                              border-radius:3px; }
.theme-toggle svg { width:1.05rem; height:1.05rem; display:block; }
@media (max-width:38rem) { .theme-toggle { margin-left:0; } }
* { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
body {
  margin:0; background:var(--bg); color:var(--fg);
  font:16px/1.65 system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  padding:2.5rem 1.25rem 4rem;
}
.wrap { max-width:var(--max); margin:0 auto; }

header.site { margin-bottom:2.5rem; }
header.site h1 { font-size:1.35rem; font-weight:600; margin:0 0 .35rem; letter-spacing:-.01em; }
header.site p { margin:0; color:var(--mut); font-size:.95rem; }

nav { margin:1.25rem 0 0; display:flex; flex-wrap:wrap; gap:1.1rem; }
nav a { color:var(--fg); text-decoration:none; font-size:.95rem; padding-bottom:2px;
        border-bottom:2px solid transparent; }
nav a:hover { border-bottom-color:var(--accent); }
nav a[aria-current="page"] { border-bottom-color:var(--accent); font-weight:600; }

main h2 { font-size:1.1rem; margin:2.5rem 0 .9rem; letter-spacing:-.005em; }
main h2:first-child { margin-top:0; }
main h3 { font-size:1rem; margin:1.6rem 0 .3rem; }
p { margin:0 0 1rem; }
a { color:var(--accent); }

.item { padding:1rem 0; border-bottom:1px solid var(--line); }
.item:last-child { border-bottom:0; }
.item h3 { margin:0 0 .25rem; }
.item .meta { color:var(--mut); font-size:.88rem; margin:0 0 .4rem; }
.item p { margin:0; }

.year { font-size:.8rem; text-transform:uppercase; letter-spacing:.08em;
        color:var(--mut); margin:2rem 0 .5rem; }
.pub { padding:.7rem 0; border-bottom:1px solid var(--line); }
.pub:last-child { border-bottom:0; }
.pub .title { font-weight:600; }
.pub .authors, .pub .venue { color:var(--mut); font-size:.9rem; }
.pub .links { font-size:.85rem; margin-top:.2rem; }

.tags { margin-top:.45rem; display:flex; flex-wrap:wrap; gap:.4rem; }
.tag { font-size:.78rem; background:var(--code); color:var(--mut);
       padding:.12rem .5rem; border-radius:3px; }

footer.site { margin-top:4rem; padding-top:1.25rem; border-top:1px solid var(--line);
              color:var(--mut); font-size:.85rem; }
footer.site a { color:var(--mut); }

@media (max-width:34rem) { body { padding:1.75rem 1rem 3rem; } }

/* --- home hero ------------------------------------------------------------ */
.hero { margin-bottom:.5rem; }
/* Wide banner rather than a circular avatar: the photo is 2.22:1, and a
   circle would crop away most of the frame -- which is the part worth
   keeping. object-fit:cover guards against distortion if the image is ever
   replaced with a different aspect ratio. */
.hero img { display:block; width:100%; height:auto; aspect-ratio:1920/863;
            object-fit:cover; object-position:center; border-radius:8px;
            background:var(--code); margin-bottom:1.4rem; }
.hero .lead p:last-child { margin-bottom:0; }

/* --- interests ------------------------------------------------------------ */
ul.plain { list-style:none; padding:0; margin:0 0 1rem; }
ul.plain li { padding:.3rem 0; border-bottom:1px solid var(--line); }
ul.plain li:last-child { border-bottom:0; }

/* --- theses grid ---------------------------------------------------------- */
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));
        gap:.9rem; margin:.5rem 0 1rem; }
.card { border:1px solid var(--line); border-radius:6px; padding:.85rem .95rem;
        background:var(--code); }
.card .t { font-weight:600; font-size:.95rem; line-height:1.35; margin:0 0 .35rem; }
.card .who { font-size:.88rem; margin:0; }
.card .kind { font-size:.78rem; color:var(--mut); margin:.3rem 0 0;
              text-transform:uppercase; letter-spacing:.06em; }
.card .links { font-size:.83rem; margin-top:.4rem; }


/* --- header layout -------------------------------------------------------- */
.head-row { display:flex; align-items:flex-start; justify-content:space-between;
            gap:2rem; }
.head-main { min-width:0; }
.head-logo { height:64px; width:auto; flex-shrink:0; margin-top:.15rem;
             opacity:.9; }
@media (max-width:38rem) {
  .head-row { flex-direction:column-reverse; align-items:flex-start; gap:1rem; }
  .head-logo { height:46px; }
}
.head-logo-link { display:block; flex-shrink:0; line-height:0; }

/* --- wordmark in dark mode ------------------------------------------------ */
/* logo-wordmark.svg is drawn entirely in currentColor, but it is loaded through
   <img>, so currentColor resolves against the SVG's OWN document -- not this
   page -- and falls back to black. Against #16161a that is invisible.
   brightness(0) flattens it to solid black (preserving the alpha channel), then
   invert(1) turns that to white; the existing opacity:.9 lands it at roughly
   #e6e6e6, essentially the --fg used by body text. Light mode is untouched.
   Repeated in both dark branches so the switch and the OS preference agree. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .head-logo { filter:brightness(0) invert(1); }
}
:root[data-theme="dark"] .head-logo { filter:brightness(0) invert(1); }

.head-logo-link:hover .head-logo { opacity:1; }
