/* ============================================================
   saulmupalia.online — design tokens and custom styling
   Tokens are defined ONCE here. Never hard-code a hex value
   anywhere else in the site.
   ============================================================ */

:root {
  /* Palette — read from the supplied design concept */
  --paper:       #F5F4F1;
  --surface:     #FFFFFF;
  --ink:         #16181D;
  --ink-muted:   #63666D;
  --accent:      #FF3E63;
  --accent-dark: #E32B4E;
  --accent-text: #D5072A;
  --tint-mint:   #E8F0E6;
  --tint-blush:  #FBE7EA;
  --footer:      #1B2030;
  --rule:        #DFDDD8;
  --on-dark:     #FFFFFF;

  /* Type */
  --font-head: "Outfit", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-body: "Inter",  system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Rhythm */
  --section-y: 5.5rem;
  --radius:    14px;

  /* Bootstrap overrides so components inherit our palette */
  --bs-body-bg: var(--paper);
  --bs-body-color: var(--ink);
  --bs-body-font-family: var(--font-body);
  --bs-border-color: var(--rule);
}

/* ---------- Base ---------- */

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
}

h1 { font-size: clamp(2.25rem, 5vw, 3.5rem); }
h2 { font-size: clamp(1.75rem, 3.5vw, 2.5rem); }
h3 { font-size: clamp(1.25rem, 2.2vw, 1.6rem); }

p { color: var(--ink); }
.lead-muted { color: var(--ink-muted); font-size: 1.0625rem; max-width: 54ch; }

/* Bootstrap 5.3 resolves link colour from --bs-link-color-rgb, so setting
   --bs-link-color has no effect. Colour links directly from our tokens. */
a { color: var(--ink); text-decoration: none; transition: color .18s ease; }
a:hover, a:focus { color: var(--accent-text); }

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

.section { padding-block: var(--section-y); }

/* Small rose label above a heading, per the concept */
.eyebrow {
  font-family: var(--font-body);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: .75rem;
  display: block;
}

/* ---------- Buttons ---------- */

.btn-accent {
  background: var(--accent);
  color: var(--on-dark);
  border: none;
  border-radius: 999px;
  padding: .8rem 1.9rem;
  font-weight: 500;
  font-family: var(--font-body);
}
.btn-accent:hover, .btn-accent:focus { background: var(--accent-dark); color: var(--on-dark); }

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: .8rem 1.9rem;
  font-weight: 500;
}
.btn-ghost:hover, .btn-ghost:focus { background: var(--ink); color: var(--paper); }

/* ---------- Navigation ---------- */

.site-nav {
  background: var(--paper);
  padding-block: 1.25rem;
  border-bottom: 1px solid transparent;
}
.site-nav .navbar-brand {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--ink);
}
.site-nav .nav-link {
  color: var(--ink);
  font-size: .95rem;
  padding-inline: .25rem;
}
.site-nav .nav-link:hover { color: var(--accent-text); }
.site-nav .nav-link.is-active { color: var(--accent-text); font-weight: 500; }

/* ---------- Tinted project panels ---------- */

.panel-mint  { background: var(--tint-mint); }
.panel-blush { background: var(--tint-blush); }
.panel {
  border-radius: var(--radius);
  padding: clamp(1.75rem, 4vw, 3rem);
}

.shot {
  border-radius: 10px;
  width: 100%;
  height: auto;
  object-fit: cover;
  object-position: top center;
  display: block;
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--footer);
  color: var(--on-dark);
  padding-block: 4.5rem 2rem;
}
.site-footer h2, .site-footer a { color: var(--on-dark); }
.footer-title { font-size: clamp(1.6rem, 3vw, 2.25rem); }
.footer-label {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .6);
  margin-bottom: .35rem;
}
.footer-email {
  font-family: var(--font-head);
  font-size: clamp(1.15rem, 2.6vw, 1.75rem);
  border-bottom: 1px solid rgba(255, 255, 255, .35);
  padding-bottom: .15rem;
}
.footer-email:hover { color: var(--accent); border-color: var(--accent); }
.footer-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }
.footer-rule { border-color: rgba(255, 255, 255, .18); margin-block: 3rem 1.5rem; }
.footer-bottom {
  display: flex; flex-wrap: wrap; gap: 1rem;
  justify-content: space-between; align-items: center;
}
.footer-social { display: flex; gap: 1.25rem; list-style: none; padding: 0; margin: 0; }
.footer-social a { color: rgba(255, 255, 255, .75); font-size: .9rem; }
.footer-social a:hover { color: var(--on-dark); }
.footer-meta { color: rgba(255, 255, 255, .55); font-size: .85rem; margin: 0; }

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- Hero ---------- */

.hero { padding-block: 3rem 4.5rem; }
.hero h1 { max-width: 12ch; }

.hero-portrait-wrap { position: relative; max-width: 380px; margin-inline: auto; }
.hero-portrait {
  width: 100%;
  aspect-ratio: 1 / 1.08;
  object-fit: cover;
  object-position: center 20%;
  border-radius: 50% 50% var(--radius) var(--radius);
  display: block;
}

.hero-badge {
  position: absolute;
  left: -46px;
  bottom: 18px;
  width: 132px;
  height: 132px;
  display: grid;
  place-items: center;
  background: var(--paper);
  border-radius: 50%;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
}
.hero-badge__ring {
  width: 100%;
  height: 100%;
  animation: badge-spin 18s linear infinite;
}
.hero-badge__text {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: .06em;
  fill: var(--ink);
  text-transform: uppercase;
}
.hero-badge__arrow {
  position: absolute;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--accent);
}
@keyframes badge-spin { to { transform: rotate(360deg); } }

@media (max-width: 991.98px) {
  .hero-badge { left: auto; right: 4px; bottom: 4px; width: 104px; height: 104px; }
  .hero-badge__text { font-size: 17px; }
}

/* ---------- Project panels ---------- */

.project-panel { margin-bottom: 1.5rem; }
.project-panel h3 { margin-bottom: .5rem; }
.project-panel .shot-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .75rem;
}
.project-panel .shot-grid > :first-child {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 7;
}
.project-panel .shot-grid > :nth-child(2),
.project-panel .shot-grid > :nth-child(3) {
  aspect-ratio: 4 / 3;
}
@media (max-width: 767.98px) {
  .project-panel .shot-grid > :first-child { aspect-ratio: 16 / 9; }
}

.stack-list { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; padding: 0; margin: 1rem 0 0; }
.stack-list li {
  font-size: .8rem;
  padding: .3rem .75rem;
  border: 1px solid rgba(22, 24, 29, .18);
  border-radius: 999px;
  color: var(--ink-muted);
}

.link-arrow { color: var(--ink); font-weight: 500; border-bottom: 1px solid var(--accent); padding-bottom: 2px; }
.link-arrow:hover { color: var(--accent-text); }

/* ---------- Skills ---------- */

.skill-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
.skill-grid li {
  list-style: none;
  padding: 1.1rem .25rem;
  border-top: 1px solid var(--rule);
  font-size: 1.0625rem;
}
@media (max-width: 767.98px) { .skill-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Credentials strip ---------- */

.stat-strip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
.stat__figure { font-family: var(--font-head); font-size: clamp(2rem, 4vw, 2.75rem); color: var(--accent); line-height: 1; }
.stat__label { color: var(--ink-muted); font-size: .95rem; margin-top: .5rem; }
@media (max-width: 575.98px) { .stat-strip { grid-template-columns: 1fr; gap: 1.5rem; text-align: center; } }

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

.post-card { background: var(--surface); border-radius: var(--radius); overflow: hidden; height: 100%; display: flex; flex-direction: column; }
.post-card__body { padding: 1.4rem; display: flex; flex-direction: column; flex: 1; }
/* Cover art, when a post has one. The fixed ratio keeps a row of cards level
   whatever shape the uploaded file was, and object-fit crops rather than
   squashes. */
/* height:auto is load-bearing. The width/height attributes on the <img> exist
   to reserve space before the file arrives, but they also act as presentational
   hints for the CSS width and height. With height left alone the hint wins,
   both dimensions become definite, and aspect-ratio is ignored — which stretched
   every card image to 640x360's height at whatever width the card happened to be. */
.post-card__media { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; background: var(--rule); }
.post-hero__media { display: block; width: 100%; height: auto; max-height: 420px; object-fit: cover; border-radius: var(--radius); margin-top: 1.5rem; }
.post-card__meta { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); }
.post-card h3 { font-size: 1.15rem; margin: .5rem 0 .6rem; }
.post-card p { color: var(--ink-muted); font-size: .95rem; flex: 1; }

/* ---------- Case study ---------- */

.case-header { padding-block: 3rem 2rem; }
.case-meta { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding-block: 1.5rem; margin-block: 2rem; }
.case-meta dt { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-muted); font-weight: 500; margin-bottom: .35rem; }
.case-meta dd { margin: 0; font-size: .95rem; }
@media (max-width: 767.98px) { .case-meta { grid-template-columns: repeat(2, 1fr); } }

.case-body { max-width: 42rem; }
.case-body h2 { font-size: 1.5rem; margin-top: 2.75rem; margin-bottom: .9rem; }
.case-body ul { padding-left: 1.15rem; }
.case-body li { margin-bottom: .5rem; }

.case-figure { margin-block: 2.5rem; }
.case-figure img { width: 100%; border-radius: var(--radius); display: block; }
.case-figure figcaption { color: var(--ink-muted); font-size: .85rem; margin-top: .65rem; }

.case-nav { border-top: 1px solid var(--rule); padding-top: 2rem; margin-top: 4rem; }

/* ---------- Timeline ---------- */

.timeline { list-style: none; padding: 0; margin: 0; border-left: 1px solid var(--rule); }
.timeline > li { position: relative; padding: 0 0 2.5rem 2rem; }
.timeline > li::before {
  content: "";
  position: absolute;
  left: -5px; top: .55rem;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--accent);
}
.timeline .role { font-family: var(--font-head); font-size: 1.15rem; font-weight: 600; margin-bottom: .15rem; }
.timeline .org { color: var(--ink); margin-bottom: .1rem; }
.timeline .when { color: var(--ink-muted); font-size: .85rem; letter-spacing: .04em; margin-bottom: .6rem; }
.timeline p:last-child { color: var(--ink-muted); margin-bottom: 0; }

.what-i-do { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem; }
.what-i-do h3 { font-size: 1.1rem; margin-bottom: .4rem; }
.what-i-do p { color: var(--ink-muted); font-size: .95rem; margin: 0; }
@media (max-width: 767.98px) { .what-i-do { grid-template-columns: 1fr; gap: 1.5rem; } }

/* ---------- Blog post ---------- */

.post-header { padding-block: 3rem 1.5rem; }
.post { max-width: 42rem; }
.post h2 { font-size: 1.45rem; margin-top: 2.5rem; margin-bottom: .8rem; }
.post p { margin-bottom: 1.15rem; }
.post ul, .post ol { padding-left: 1.15rem; margin-bottom: 1.15rem; }
.post li { margin-bottom: .45rem; }
.post blockquote {
  border-left: 3px solid var(--accent);
  padding-left: 1.25rem;
  margin: 2rem 0;
  color: var(--ink-muted);
  font-size: 1.05rem;
}

/* ---------- Contact ---------- */

.contact-row { border-top: 1px solid var(--rule); padding-block: 1.4rem; display: flex; flex-wrap: wrap; gap: .5rem 2rem; align-items: baseline; }
.contact-row:last-child { border-bottom: 1px solid var(--rule); }
.contact-row dt { flex: 0 0 9rem; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-muted); font-weight: 500; }
.contact-row dd { margin: 0; font-size: 1.05rem; }
.contact-lead { font-family: var(--font-head); font-size: clamp(1.5rem, 3.5vw, 2.25rem); border-bottom: 2px solid var(--accent); padding-bottom: .2rem; }

/* Contact-form honeypot. Positioned off-screen rather than display:none,
   because some bots skip fields that are display:none — which would defeat
   the point of having the field at all. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden;
}

.contact-form .form-control:focus {
  border-color: var(--accent, #3525cd);
  box-shadow: 0 0 0 0.2rem rgba(53, 37, 205, 0.15);
}

/* Shown to a signed-in owner on a page their Settings switch has hidden from
   everyone else. Deliberately loud: the whole point is that it cannot be
   mistaken for part of the page. */
.hidden-notice {
  background: var(--accent);
  color: var(--on-dark);
  padding-block: .75rem;
  font-size: .95rem;
}
.hidden-notice a { color: var(--on-dark); text-decoration: underline; }

/* ---------- Support section ---------- */

.support-form__legend { font-family: var(--font-head); font-size: 1.1rem; font-weight: 600; margin-bottom: .75rem; }
.support-label { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: .35rem; display: block; }

.support-amounts { display: flex; flex-wrap: wrap; gap: .5rem; }
.support-amount {
  border: 1px solid var(--rule);
  background: var(--surface);
  border-radius: 999px;
  padding: .5rem 1.1rem;
  font-size: .9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.support-amount:hover { border-color: var(--accent); color: var(--accent-text); }
.support-amount.is-chosen { background: var(--accent); border-color: var(--accent); color: var(--on-dark); }

.support-form .form-control { border-color: var(--rule); border-radius: 10px; padding: .7rem .9rem; }
.support-form .form-control:focus { border-color: var(--accent); box-shadow: 0 0 0 .2rem rgba(255, 62, 99, .15); }

.support-status { margin: 1rem 0 0; font-size: .95rem; min-height: 1.5rem; }
.support-status.is-ok { color: #1a7f4b; font-weight: 500; }
.support-status.is-error { color: var(--accent-text); }
.support-status.is-warn { color: #8a5b00; }

.support-note {
  background: var(--surface);
  border-left: 3px solid var(--accent);
  padding: .75rem 1rem;
  border-radius: 8px;
  font-size: .9rem;
}

.support-paybill { margin: 1.5rem 0 .5rem; }
.support-paybill dt { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: .6rem; }
.support-paybill dd { display: flex; align-items: baseline; gap: .75rem; margin: 0 0 .4rem; }
.support-paybill__label { font-size: .85rem; color: var(--ink-muted); min-width: 5.5rem; }
/* Monospace so a payer reading the number aloud, or typing it into a phone,
   is not tripped by a 1 that looks like an l. */
.support-paybill__value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.15rem; letter-spacing: .05em; }
.support-hint { font-size: .85rem; color: var(--ink-muted); margin: 0; }
