/* ============================================================
   Manu Lobato — Portfolio
   Pure HTML5 + CSS · Cross-document View Transitions
   Design language: "the request line" — backend vernacular
   (HTTP methods, routes, status codes) treated with Swiss
   typographic discipline.
   ============================================================ */

/* ---------- Fonts (self-hosted, latin subset) ----------
   Served from the embedded binary and preloaded in <head>, so the
   real typeface is ready at first paint — no fallback-to-webfont swap. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("/static/fonts/archivo-latin.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("/static/fonts/jetbrains-mono-latin.woff2") format("woff2");
}

/* ---------- Design tokens ---------- */
:root {
  --paper: #f3f4f1;
  --surface: #fbfbf9;
  --ink: #161b1d;
  --muted: #5b6562;
  --line: #dce0db;
  --line-strong: #c3c9c2;

  --accent: #0e7c86;       /* petrol teal — GET, links, focus     */
  --accent-deep: #0a5a61;
  --accent-soft: #e2efef;
  --amber: #a86b08;        /* POST — the one action on the site   */
  --amber-soft: #f5ead3;
  --indigo: #585fa8;       /* a quiet nod to PHP                  */

  --font-display: "Archivo", system-ui, sans-serif;
  --font-body: "Archivo", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --maxw: 1080px;
  --radius: 6px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
}

/* ---------- View transitions (cross-document) ---------- */
@view-transition {
  navigation: auto;
}

/* Page body: old content lifts away, new content settles in */
::view-transition-old(root) {
  animation: 240ms var(--ease-in) both vt-leave;
}
::view-transition-new(root) {
  animation: 420ms var(--ease-out) both vt-enter;
}
@keyframes vt-leave {
  to {
    opacity: 0;
    transform: translateY(-14px);
  }
}
@keyframes vt-enter {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
}

/* Persistent chrome: header and footer hold still while
   the page beneath them changes */
.site-header {
  view-transition-name: site-header;
}
.site-footer {
  view-transition-name: site-footer;
}

/* The page title morphs from one route to the next */
.page-title {
  view-transition-name: page-title;
}
.request-line {
  view-transition-name: request-line;
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
  * {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ---------- Reset & base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  border-top: 4px solid var(--accent);
  /* Full-height flex column so the footer can be pushed to the bottom of the
     viewport on short pages — <main> grows to absorb any leftover space. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* Take up the slack: on a short page this stretches so the footer lands at the
   bottom of the viewport; on a long page it just wraps its content as usual. */
main {
  flex: 1 0 auto;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: var(--accent-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover {
  color: var(--accent);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection {
  background: var(--accent);
  color: #fff;
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 1.5rem;
}

.mono {
  font-family: var(--font-mono);
}

/* ---------- Header / navigation ---------- */
.site-header {
  background: var(--paper);
  border-bottom: 1px solid var(--line-strong);
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 0.9rem;
  padding-bottom: 0.9rem;
}

.brand {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.brand:hover {
  color: var(--accent-deep);
}
.brand .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.site-nav {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.site-nav a {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  text-decoration: none;
  color: var(--muted);
  padding: 0.4rem 0.65rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  transition: color 140ms ease, background 140ms ease, border-color 140ms ease;
}

.site-nav a .method {
  font-weight: 700;
  color: var(--accent);
  margin-right: 0.45em;
}
.site-nav a .method.post {
  color: var(--amber);
}

.site-nav a:hover {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--line);
}

.site-nav a[aria-current="page"] {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--line-strong);
}

/* Hamburger toggle — hidden on desktop, the nav shows inline. */
.nav-toggle,
.nav-toggle-btn {
  display: none;
}

/* ---------- Page intro: request line + title ---------- */
.page-intro {
  padding: 4.5rem 0 3rem;
}

.request-line {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin: 0 0 1.4rem;
  display: inline-flex;
  align-items: baseline;
  gap: 0.75em;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  padding: 0.45rem 0.8rem;
  border-radius: 999px;
}
.request-line .method {
  color: var(--accent);
  font-weight: 700;
}
.request-line .method.post {
  color: var(--amber);
}
.request-line .status {
  color: var(--accent-deep);
  font-weight: 500;
}

.page-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 118%;
  font-size: clamp(2.6rem, 7vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin: 0 0 1.2rem;
  text-wrap: balance;
}
.page-title .slash {
  color: var(--accent);
}

.lede {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--muted);
  max-width: 46em;
  margin: 0;
}
.lede strong {
  color: var(--ink);
  font-weight: 600;
}

/* ---------- Sections ---------- */
.section {
  padding: 3.2rem 0;
}

.section-head {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 0 0 2rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
}
.section-head .code {
  color: var(--accent-deep);
  font-weight: 700;
}
.section-head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.section h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 112%;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 1.4rem;
}

/* ---------- Hero meta row (home) ---------- */
.hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 2.2rem;
}
.hero-meta span {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
}

/* ---------- Skills ---------- */
.skill-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.skill-cell {
  background: var(--surface);
  padding: 1.4rem 1.5rem 1.6rem;
}
.skill-cell h3 {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin: 0 0 0.9rem;
}
.skill-cell ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}
.skill-cell li {
  font-size: 0.88rem;
  border: 1px solid var(--line-strong);
  background: var(--paper);
  border-radius: 999px;
  padding: 0.22rem 0.7rem;
  color: var(--ink);
}
.skill-cell li.hot {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-weight: 600;
}

/* ---------- Experience timeline ---------- */
.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.timeline li {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 1.6rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--line);
}
.timeline li:last-child {
  border-bottom: none;
}

.timeline .when {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--muted);
  padding-top: 0.3rem;
  white-space: nowrap;
}

.timeline h3 {
  margin: 0 0 0.15rem;
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.timeline .org {
  font-size: 0.92rem;
  color: var(--muted);
  margin: 0 0 0.55rem;
}
.timeline p.desc {
  margin: 0;
  color: var(--ink);
  font-size: 0.97rem;
  max-width: 56em;
}

/* ---------- Cards (projects / blog) ---------- */
.card-list {
  display: grid;
  gap: 1.2rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 1.7rem 1.8rem 1.8rem;
  transition: border-color 160ms ease, transform 160ms var(--ease-out),
    box-shadow 160ms ease;
}
.card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -18px rgba(14, 124, 134, 0.55);
}

.card .meta {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin: 0 0 0.8rem;
}
.card .meta .id {
  color: var(--accent-deep);
  font-weight: 700;
}

.card h3 {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 110%;
  font-size: 1.35rem;
  letter-spacing: -0.015em;
  margin: 0 0 0.6rem;
}

.card p {
  margin: 0 0 1rem;
  color: var(--ink);
  max-width: 62em;
}
.card p:last-of-type {
  margin-bottom: 0;
}

.tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 1.1rem 0 0;
  padding: 0;
}
.tags li {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 0.2rem 0.55rem;
}
.tags li.alt {
  color: var(--indigo);
  background: #e9eaf5;
}

/* Blog-specific */
.post .when {
  color: var(--muted);
}
.post h3 {
  font-size: 1.45rem;
}
.read-note {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}

/* Project-card actions: the live-demo + write-up buttons. */
.project-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin: 1.3rem 0 0;
}
.project-actions .btn {
  font-size: 0.82rem;
  padding: 0.6rem 1.1rem;
}

/* Secondary button: outlined, for the lower-emphasis action. */
.btn-outline {
  color: var(--accent-deep);
  background: transparent;
  border-color: var(--line-strong);
}
.btn-outline:hover {
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-color: var(--accent);
  filter: none;
}

/* A card that is itself a link (e.g. a blog post in the list). */
a.card {
  display: block;
  text-decoration: none;
  color: inherit;
}
a.card h3 {
  color: var(--ink);
  transition: color 160ms ease;
}
a.card:hover h3 {
  color: var(--accent-deep);
}

/* ---------- Blog post (single entry) ---------- */
.post-head {
  padding-bottom: 2rem;
}
.post-title {
  font-size: clamp(2rem, 5.5vw, 3.4rem);
}
.post-byline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  font-size: 0.78rem;
  color: var(--muted);
  margin: 1.4rem 0 0;
}
.post-byline .id {
  color: var(--accent-deep);
  font-weight: 700;
}

/* Article prose — a single readable column. */
.prose {
  max-width: 44em;
}
.prose > :first-child {
  margin-top: 0;
}
.prose p {
  margin: 0 0 1.3rem;
}
.prose h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 112%;
  font-size: clamp(1.35rem, 3vw, 1.8rem);
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 2.6rem 0 1rem;
}
.prose ul {
  margin: 0 0 1.3rem;
  padding-left: 1.2rem;
}
.prose li {
  margin: 0 0 0.5rem;
}
.prose strong {
  font-weight: 600;
}
.prose a {
  color: var(--accent-deep);
}
.prose code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--accent-soft);
  color: var(--accent-deep);
  padding: 0.1em 0.4em;
  border-radius: 4px;
}
.prose pre {
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  margin: 0 0 1.5rem;
  overflow-x: auto;
  font-size: 0.85rem;
  line-height: 1.55;
}
.prose pre code {
  background: none;
  color: inherit;
  padding: 0;
  font-size: inherit;
}
.prose blockquote {
  margin: 0 0 1.5rem;
  padding: 0.4rem 0 0.4rem 1.3rem;
  border-left: 3px solid var(--accent);
  color: var(--muted);
  font-size: 1.08rem;
  font-style: italic;
}

.back-link {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.84rem;
  text-decoration: none;
  color: var(--muted);
  transition: transform 160ms var(--ease-out), color 160ms ease;
}
.back-link .method {
  color: var(--accent);
  font-weight: 700;
}
.back-link:hover {
  color: var(--accent-deep);
  transform: translateX(-3px);
}

/* The back-arrow that sits above a post title. */
.post-head .back-link {
  margin-bottom: 1.4rem;
}

/* ---------- Contact ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  gap: 2.5rem;
  align-items: start;
}

.channel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}
.channel-list a {
  display: block;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  color: var(--ink);
  transition: border-color 160ms ease, transform 160ms var(--ease-out);
}
.channel-list a:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.channel-list .label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
  margin-bottom: 0.25rem;
}
.channel-list .value {
  font-weight: 600;
  font-size: 0.98rem;
  word-break: break-all;
}

/* Form */
.contact-form {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 1.8rem;
}

.contact-form .form-head {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
  margin: 0 0 1.4rem;
  padding-bottom: 1rem;
  border-bottom: 1px dashed var(--line-strong);
}
.contact-form .form-head .method {
  color: var(--amber);
  font-weight: 700;
}

.field {
  margin-bottom: 1.2rem;
}
.field label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.field input,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 0.97rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field textarea {
  resize: vertical;
  min-height: 150px;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 700;
  color: #fff;
  background: var(--amber);
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  padding: 0.75rem 1.4rem;
  cursor: pointer;
  transition: filter 140ms ease, transform 140ms var(--ease-out);
}
.btn:hover {
  /* Keep the label white — without this, the global `a:hover` rule (more
     specific than `.btn`) recolors it to --accent, which vanishes against
     the teal CTA button. */
  color: #fff;
  filter: brightness(1.08);
  transform: translateY(-1px);
}
.btn:active {
  transform: translateY(0);
}

.form-note {
  font-size: 0.84rem;
  color: var(--muted);
  margin: 1rem 0 0;
}

/* Validation / send error shown above the form fields. */
.form-error {
  font-family: var(--font-mono);
  font-size: 0.84rem;
  color: var(--amber);
  background: var(--amber-soft);
  border: 1px solid var(--amber);
  border-radius: var(--radius);
  padding: 0.7rem 0.9rem;
  margin: 0 0 1.4rem;
}
.form-error .status {
  font-weight: 700;
  margin-right: 0.4em;
}

/* ---------- CTA strip (home) ---------- */
.cta-strip {
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius);
  padding: 2.4rem 2.2rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.4rem;
}
.cta-strip h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 112%;
  letter-spacing: -0.02em;
  font-size: clamp(1.3rem, 3vw, 1.8rem);
}
.cta-strip .sub {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 400;
  font-stretch: 100%;
  letter-spacing: 0.03em;
  color: #aebab7;
  margin-top: 0.5rem;
}
.cta-strip .btn {
  background: var(--accent);
  border-color: var(--accent);
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--line-strong);
  margin-top: 4rem;
  background: var(--paper);
}
.site-footer .wrap {
  padding-top: 1.6rem;
  padding-bottom: 2rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.8rem 2rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.site-footer a {
  color: var(--muted);
}
.site-footer a:hover {
  color: var(--accent-deep);
}
/* Desktop: lock the footer to a fixed height so it can't grow. Without this,
   long pages add a scrollbar that narrows the viewport just enough to wrap the
   row onto two lines, making the footer taller than on short pages. Keeping it
   on one centred row (nowrap) holds the height constant. Mobile keeps its
   stacked layout via the max-width: 760px block below. */
@media (min-width: 761px) {
  .site-footer {
    height: 4.75rem;
    display: flex;
    align-items: center;
  }
  .site-footer .wrap {
    width: 100%;
    padding-top: 0;
    padding-bottom: 0;
    flex-wrap: nowrap;
  }
}

/* Honeypot: kept in the DOM (so bots fill it) but out of sight and out of the
   tab order for real visitors. Not display:none — some bots skip those. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Responsive ---------- */
@media (max-width: 760px) {
  /* Centre the footer's two lines when they stack on small screens. */
  .site-footer .wrap {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .page-intro {
    padding: 3rem 0 2.4rem;
  }
  .timeline li {
    grid-template-columns: 1fr;
    gap: 0.3rem;
  }
  .contact-grid {
    grid-template-columns: 1fr;
  }

  /* ----- Mobile header: brand + hamburger on one row, nav drops below ----- */
  .site-header .wrap {
    position: relative;
    align-items: center;
    gap: 0.6rem 1rem;
  }

  /* Decorative hamburger icon (three bars). */
  .nav-toggle-btn {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    margin-left: auto;
    padding: 0 9px;
    border: 0;
    background: transparent;
  }
  .nav-toggle-btn .bar {
    height: 2px;
    width: 100%;
    background: var(--ink);
    border-radius: 2px;
    transition: transform 220ms var(--ease-out), opacity 160ms ease;
  }

  /* The real control: an invisible checkbox laid over the icon. It stays
     keyboard-focusable, so Space toggles the menu with no JavaScript. */
  .nav-toggle {
    display: block;
    position: absolute;
    top: 0.9rem;
    right: 1.5rem;
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 11;
  }
  .nav-toggle:focus-visible ~ .nav-toggle-btn {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
  }

  /* Nav is collapsed by default, revealed when the checkbox is checked. */
  .site-nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    gap: 0.3rem;
    padding-bottom: 0.4rem;
  }
  .nav-toggle:checked ~ .site-nav {
    display: flex;
  }
  .site-nav a {
    font-size: 0.95rem;
    padding: 0.65rem 0.8rem;
  }

  /* Bars morph into an X when the menu is open. */
  .nav-toggle:checked ~ .nav-toggle-btn .bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }
  .nav-toggle:checked ~ .nav-toggle-btn .bar:nth-child(2) {
    opacity: 0;
  }
  .nav-toggle:checked ~ .nav-toggle-btn .bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }
}
