/* ============================================================
   Ivan Santiago — consultancy & advisory
   Hand-built. No framework, no build step, no dependencies.
   ============================================================ */

/* ---------- 1. Fonts (self-hosted, no third-party requests) ---------- */

@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin-700-normal.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-latin-800-normal.woff2') format('woff2');
  font-weight: 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-latin-400-italic.woff2') format('woff2');
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}


/* ---------- 2. Tokens ---------- */

:root {
  --paper:    #ffffff;
  --ink:      #2b2b2b;
  --ink-soft: #6e6e6e;
  --rule:     #e4e4e4;
  --link:     #1f5c8b;

  --sans:  'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --serif: 'Source Serif 4', Georgia, 'Times New Roman', serif;

  --rail-w:  19.5rem;
  --gutter:  clamp(1.5rem, 5vw, 6rem);
  --band-y:  clamp(4rem, 9vw, 8.5rem);
  --measure: 60ch;   /* ~60 characters — the comfortable reading measure */
}


/* ---------- 3. Reset ---------- */

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

html { -webkit-text-size-adjust: 100%; }

body,
h1, h2, h3, p, ul, ol, dl, dd, figure, form {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }

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

button, input, textarea { font: inherit; color: inherit; }


/* ---------- 4. Base ---------- */

html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 100%;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--link); }

::selection { background: #d8e6f1; color: var(--ink); }

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


/* ---------- 5. Skip link ---------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 0.7rem 1rem;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { left: 0; }


/* ---------- 6. Shell ---------- */

/* The rail and the footer share column 1. The footer sticky-pins itself to the
   viewport bottom the way the reference site's sidebar footer does.

   min-height is what makes that safe. Without it the grid row is only as tall
   as the tallest column, so on a page with little content the row collapses —
   and a sticky element cannot leave its containing block, so the footer gets
   dragged up into the nav. That is not hypothetical: with the row at 568px the
   nav ran to 568 and the footer sat at 490, printing on top of the last two
   links. Guaranteeing a viewport of height keeps the footer below the rail.
   (Windows too short for both are handled separately, near the end of file.) */
.shell {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  column-gap: clamp(2rem, 6vw, 7rem);
  min-height: 100vh;
  max-width: 96rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}


/* ---------- 7. Rail (sidebar) ---------- */

.rail {
  grid-area: 1 / 1;
  position: sticky;
  top: 0;
  align-self: start;
  padding-block: clamp(2.5rem, 6vw, 4.5rem) 0;
}

.main { grid-area: 1 / 2; }

.base {
  grid-area: 1 / 1;
  align-self: end;
  position: sticky;
  bottom: 2rem;
  padding-top: 2rem;
  font-size: 0.8rem;
}

.base__meta { color: var(--ink-soft); }

.base__meta a {
  color: var(--ink);
  text-underline-offset: 2px;
}

.base__copy {
  margin-top: 0.5rem;
  color: var(--ink-soft);
}

.rail__photo {
  width: 6rem;
  height: 6rem;
  border-radius: 50%;
  object-fit: cover;
  background: #f0f0f0;
}

/* El Desenredo, sitting directly above the name. The mark is used exactly as
   supplied — never rescaled non-uniformly, recoloured, or redrawn. */
.rail__logo {
  display: block;
  width: 8.25rem;
  margin-top: 1.6rem;
}

.rail__logo img { width: 100%; height: auto; }

.rail__name {
  margin-top: 0.9rem;
  font-size: 2.05rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
}

.rail__tag {
  margin-top: 0.6rem;
  max-width: 15em;
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.38;
}

.rail__nav { margin-top: 2.1rem; }


/* ---------- 8. Nav ---------- */

.nav__item + .nav__item { margin-top: 0.42rem; }

.nav__link {
  position: relative;
  display: inline-block;
  color: var(--ink);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.16;
  text-decoration: none;
  transition: color 0.18s ease;
}

/* The current page is struck through, as on the reference site. Driven by
   aria-current, so it needs no JavaScript and stays correct for screen readers. */
.nav__link::after {
  content: "";
  position: absolute;
  left: -0.03em;
  right: -0.03em;
  top: calc(50% - 0.05em);
  height: 0.1em;
  background: currentColor;
  opacity: 0;
}

.nav__link:hover { color: var(--link); }

.nav__link[aria-current="page"]::after { opacity: 1; }


/* ---------- 9. Main + bands ---------- */

.main { min-width: 0; }

.band {
  padding-block: var(--band-y) 0;
  scroll-margin-top: 1.5rem;
}

.band:last-child { padding-bottom: var(--band-y); }

.band--hero { padding-top: clamp(3rem, 8vw, 7rem); }

/* Inner pages start near the top, roughly level with the sidebar identity */
.band--page { padding-top: clamp(2.5rem, 6vw, 4.5rem); }


/* ---------- 10. Shared type ---------- */

.eyebrow {
  color: var(--ink-soft);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

/* El saludo de inicio no es una etiqueta como los otros eyebrows ("SERVICIOS",
   "CONTACTO"): es una frase, y en caja alta suena a rotulo. Mismo tamano, mismo
   peso, mismo color; solo cambia la caja. El tracking baja porque 0.13em esta
   pensado para mayusculas y en minusculas deja las letras sueltas. */
.eyebrow--saludo {
  font-size: 1.1rem;
  text-transform: none;
  letter-spacing: 0.01em;
}

/* El balance reparte los renglones para que ninguno quede mucho mas corto que
   el otro, y con la frase actual alcanza. Si algun dia entra un titular que
   gira sobre una coma en medio, el balance no basta: el navegador corta por
   donde se le acaba el ancho y puede partir la frase justo en la bisagra. Ese
   caso pide envolver cada mitad en su propio bloque. */
.hero__line {
  margin-top: 1.6rem;
  max-width: 22ch;
  font-size: clamp(2.9rem, 7.4vw, 5.6rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.95;
  text-wrap: balance;
}

.head {
  margin-top: 1.3rem;
  max-width: 22ch;
  font-size: clamp(2rem, 4.4vw, 3.3rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.03;
  text-wrap: balance;
}

.prose {
  margin-top: 1.9rem;
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.3125rem;
  line-height: 1.62;
  hyphens: auto;
}

.prose p + p { margin-top: 1.3rem; }

.prose--lead { max-width: 52ch; font-size: 1.45rem; }

.prose a { text-underline-offset: 3px; }


/* ---------- 11. Hero CTA ---------- */

.hero__cta { margin-top: 2.4rem; }

.cta {
  display: inline-block;
  font-size: 1.08rem;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

.cta__arrow {
  display: inline-block;
  transition: transform 0.22s ease;
}

.cta:hover .cta__arrow { transform: translateX(0.25rem); }


/* ---------- 12. Services ---------- */

.offer { margin-top: 2.9rem; max-width: 40em; }

.offer__row { padding-block: 1.9rem; border-top: 1px solid var(--rule); }

.offer__row:last-child { border-bottom: 1px solid var(--rule); }

.offer__name {
  font-size: 1.28rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.offer__body {
  margin-top: 0.7rem;
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.19rem;
  line-height: 1.6;
}

.offer__note {
  margin-top: 0.75rem;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}


/* ---------- 13. Approach steps ---------- */

.steps { margin-top: 3rem; max-width: 40em; }

.steps__item + .steps__item { margin-top: 2.8rem; }

.steps__num {
  display: block;
  color: var(--ink-soft);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
}

.steps__name {
  margin-top: 0.6rem;
  font-size: 1.42rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.steps__body {
  margin-top: 0.65rem;
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.19rem;
  line-height: 1.6;
}


/* ---------- 14. Herramientas: lista de descargas ---------- */

.tools { margin-top: 3rem; max-width: 40em; list-style: none; }

/* Mismo tratamiento de renglon que .offer: las dos son listas de cosas que se
   comparan de un vistazo, y conviene que se lean igual. */
.tools__item { padding-block: 1.9rem; border-top: 1px solid var(--rule); }

.tools__item:last-child { border-bottom: 1px solid var(--rule); }

.tools__name {
  font-size: 1.28rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.tools__body {
  margin-top: 0.7rem;
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.19rem;
  line-height: 1.6;
}

.tools__get { margin-top: 1rem; }

/* El formato y el peso viven dentro del enlace, no al lado: quien navega por
   teclado o con lector de pantalla los recibe junto con el enlace y no como
   un texto suelto que quedo huerfano en otra parte del documento. */
.tools__meta {
  margin-left: 0.15em;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}


/* ---------- 15. Sobre mi: texto y retrato ---------- */

/* Apilado por defecto: titulo, texto y despues el retrato. El espacio lo pone
   el row-gap, no el margen de .prose, para que en dos columnas el parrafo y la
   foto puedan arrancar exactamente a la misma altura. */
.about { display: grid; row-gap: 1.9rem; }

.about__prose { margin-top: 0; }

/* Apilado, el retrato a ancho completo se comeria la pantalla: la foto mide
   4:5, asi que a 40rem de ancho saldria a 50rem de alto. El margen extra
   completa la separacion mayor que pide una imagen despues de un bloque. */
.about__figure { margin: 0.9rem 0 0; max-width: 22rem; }

.about__img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  background: #f0f0f0;
}

/* Dos columnas solo cuando de verdad caben, y eso pasa mas tarde de lo que
   parece: la barra lateral se lleva 19.5rem antes de que empiece el contenido,
   asi que la columna de texto es ~34rem mas angosta que la ventana. Con la
   foto ocupando 0.58fr hace falta llegar a 84rem para que al texto le queden
   ~48 caracteres por linea; abajo de eso se cae a menos de 45, que es el
   minimo legible para el cuerpo en serif. Si mueves un numero, vuelve a medir
   el ancho del texto y la proporcion de la foto. */
@media (min-width: 84rem) {
  .about {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.58fr);
    grid-template-areas:
      "head  ."
      "prose figure";
    column-gap: 3.2rem;
  }

  .about__head   { grid-area: head; }
  .about__prose  { grid-area: prose; }

  /* El retrato arranca en la primera linea del parrafo, pero NO se estira
     hasta el final del texto. Se intento y no se sostiene: con la biografia
     actual el bloque de texto mide ~1015px de alto, y a lo ancho de esta
     columna eso daba una foto de 311x1015 — proporcion 0.31 contra 0.80 del
     archivo, o sea 62% del ancho de la imagen recortado. Una astilla.

     Estirar la foto solo funcionaba cuando el texto eran tres parrafos
     cortos; la altura del texto no es un parametro que el diseno controle.
     Asi que manda la proporcion del archivo (4:5, cero recorte) y la foto se
     alinea arriba. Si algun dia el texto vuelve a ser corto y quieres que
     cierren parejo abajo, hay que fijar la altura a mano y revisarla cada vez
     que cambie la copia. */
  .about__figure {
    grid-area: figure;
    align-self: start;
    margin: 0;
    max-width: none;
  }
}


/* ---------- 16. Contact form ---------- */

.form { margin-top: 2.9rem; max-width: 31rem; }

.field + .field { margin-top: 1.5rem; }

.field__label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.83rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.field__input {
  width: 100%;
  padding: 0.72rem 0.85rem;
  background: var(--paper);
  /* #8c8c8c clears WCAG 1.4.11's 3:1 minimum for control boundaries (3.4:1) */
  border: 1px solid #8c8c8c;
  border-radius: 0;
  font-family: var(--sans);
  font-size: 1rem;
  transition: border-color 0.16s ease;
}

.field__input:hover { border-color: #5f5f5f; }

.field__input:focus {
  border-color: var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: -2px;
}

.field__input--area { resize: vertical; min-height: 7rem; line-height: 1.5; }

.field__input.is-wrong { border-color: #a8332a; }

.field__error {
  margin-top: 0.4rem;
  color: #a8332a;
  font-size: 0.83rem;
}

.trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.trap input { width: 1px; }

.submit {
  margin-top: 1.9rem;
  padding: 0.82rem 2.1rem;
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 0;
  font-size: 0.97rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}

.submit:hover { background: var(--paper); color: var(--ink); }

.submit[disabled] { opacity: 0.5; cursor: default; }

.submit[disabled]:hover { background: var(--ink); color: var(--paper); }

.form__status {
  margin-top: 1.1rem;
  font-size: 0.95rem;
  line-height: 1.5;
}

.form__status:empty { margin-top: 0; }

.form__status.is-ok { color: #1d6b45; }

.form__status.is-bad { color: #a8332a; }


/* ---------- 17. Phone: rail unpins, stacks on top ---------- */

/* Solo hay dos versiones del sitio. Abajo de 44rem, esta: una columna, con la
   identidad y el menu arriba del contenido. De 44rem para arriba, la barra
   lateral a la izquierda, igual en tablet que en escritorio; la tablet solo
   ajusta proporciones, no cambia de estructura. */
@media (max-width: 44rem) {

  /* One column, natural document order: identity + nav, content, footer. */
  .shell { display: block; }

  .rail {
    position: static;
    padding-block: clamp(2rem, 7vw, 3rem) 0;
  }

  /* El retrato a la izquierda y, a su derecha, una pila de tres: marca,
     nombre y descriptor. El retrato abarca los tres renglones, asi que la
     pila y el circulo empiezan y terminan a la misma altura.

     Que cierren parejo es aritmetica, no suerte: los tres renglones tienen
     que sumar el alto del circulo (4.6rem = 73.6px). Nombre y descriptor
     aportan sus interlineados (28.9 + 21 = 49.9px), y lo que sobra, 23.7px,
     es el alto de la marca. Como la marca es 2.5 veces mas ancha que alta,
     eso fija su ancho en 3.7rem. Si cambias el tamano del nombre o del
     descriptor, este numero deja de cuadrar y hay que recalcularlo. */
  .rail__top {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "photo logo"
      "photo name"
      "photo tag"
      "nav   nav";
    column-gap: 1.1rem;
  }

  .rail__logo {
    grid-area: logo;
    align-self: start;
    width: 3.7rem;
    margin: 0;
  }

  .rail__photo {
    grid-area: photo;
    align-self: start;
    width: 4.6rem;
    height: 4.6rem;
  }

  .rail__name {
    grid-area: name;
    align-self: end;
    margin-top: 0;
    font-size: 1.72rem;
  }

  /* Sin margen arriba: cualquier separacion extra aqui rompe la suma que
     hace que la pila cierre exactamente con el circulo. */
  .rail__tag {
    grid-area: tag;
    align-self: start;
    margin-top: 0;
    max-width: 24em;
    font-size: 0.95rem;
  }

  .rail__nav {
    grid-area: nav;
    margin-top: 1.7rem;
    padding-top: 1.4rem;
    border-top: 1px solid var(--rule);
  }

  /* Reticula fija de tres por renglon: inicio / servicios / enfoque arriba,
     herramientas / sobre mi / contacto abajo. Antes era flex con wrap, y el
     corte se movia con el ancho de la pantalla: en unos telefonos quedaban
     4+2, en otros 3+3. Con la reticula el reparto no depende del ancho.

     min-content como minimo evita que "herramientas", que no puede partirse,
     se salga de su columna; el 1fr reparte lo que sobre en partes iguales,
     asi las dos filas caen en las mismas tres verticales. */
  /* Reticula fija de tres por renglon: inicio / servicios / enfoque arriba,
     herramientas / sobre mi / contacto abajo. Antes era flex con wrap y el
     corte se movia con el ancho: 4+2 en unos telefonos, 3+3 en otros.

     min-content como minimo evita que "herramientas", que no puede partirse,
     se salga de su columna; el 1fr reparte lo que sobre en partes iguales,
     asi las dos filas caen en las mismas tres verticales.

     El tamano es fluido porque las tres columnas piden "herramientas" +
     "servicios" + "enfoque" mas los huecos: a 18.9px son 320px, que con los
     margenes exigen una ventana de 392px. A tamano fijo el menu se desbordaba
     justo en los telefonos mas comunes, 375 y 390. */
  .nav {
    display: grid;
    grid-template-columns: repeat(3, minmax(min-content, 1fr));
    column-gap: clamp(0.6rem, 3vw, 1.2rem);
    row-gap: 0.5rem;
    justify-items: start;
  }

  .nav__item + .nav__item { margin-top: 0; }

  .nav__link { font-size: clamp(0.9rem, 4.4vw, 1.18rem); }

  /* Footer unpins and sits at the true foot of the page */
  .base {
    position: static;
    margin-top: var(--band-y);
    padding-top: 1.5rem;
    padding-bottom: 2.5rem;
    border-top: 1px solid var(--rule);
  }

  /* The last band no longer needs to reserve space above the footer */
  .band:last-child { padding-bottom: 0; }

  .band--hero { padding-top: clamp(2.5rem, 9vw, 4rem); }
}


/* ---------- 17b. Tablet: misma estructura, proporciones mas apretadas ------ */

/* La tablet usa el mismo armado que el escritorio, con la barra a la
   izquierda. Lo unico que cambia son las medidas, y hace falta cambiarlas:
   la barra se lleva 19.5rem antes de que empiece el contenido, asi que a
   768px de ventana la columna de texto quedaba en 333px, unos 29 caracteres
   por renglon. Es la mitad de una medida de lectura decente.

   Estrechando la barra a 12rem y apretando margenes y separacion, mas un
   cuerpo un punto menor, la misma ventana pasa a 480px y ~48 caracteres. La
   estructura no cambia: barra a la izquierda, menu vertical, pie abajo. */
@media (min-width: 44.0625rem) and (max-width: 60rem) {

  :root {
    --rail-w: 12rem;
    --gutter: 1.75rem;
    --band-y: clamp(3rem, 7vw, 5rem);
  }

  .shell { column-gap: 2.5rem; }

  .rail { padding-block: clamp(2rem, 5vw, 3rem) 0; }

  .rail__photo { width: 5rem; height: 5rem; }

  .rail__logo { width: 7rem; margin-top: 1.1rem; }

  .rail__name { margin-top: 0.7rem; font-size: 1.55rem; }

  .rail__tag { margin-top: 0.45rem; font-size: 0.92rem; }

  .rail__nav { margin-top: 1.6rem; }

  .nav__link { font-size: 1.22rem; }

  .nav__item + .nav__item { margin-top: 0.3rem; }

  .prose { font-size: 1.25rem; }
  .prose--lead { font-size: 1.3rem; }

  .offer__body,
  .steps__body,
  .tools__body { font-size: 1.15rem; }

  .base { font-size: 0.76rem; }
}


/* Short desktop windows: unpin the footer so it can't collide with the nav.
   The sidebar runs ~580px tall, plus a 78px footer and its 32px offset, so
   anything under about 710px would overlap. 45rem (720px) clears it. */
@media (min-width: 44.0625rem) and (max-height: 45rem) {
  .base { position: static; }
}


/* ---------- 18. Phone ---------- */

@media (max-width: 34rem) {

  .prose { font-size: 1.19rem; }
  .prose--lead { font-size: 1.26rem; }

  .offer__body,
  .steps__body,
  .tools__body { font-size: 1.11rem; }

  .hero__line { max-width: none; }

  .submit { width: 100%; }
}


/* Telefonos muy angostos (abajo de ~344px, iPhone SE de primera generacion).
   Ahi la columna del texto baja a ~181px y "Consultor, asesor, operador."
   (~205px) se parte en dos renglones, con lo que la pila se pasa 21px del
   circulo. Se achica el descriptor para que vuelva a un renglon, y la marca
   se recalcula para que los tres sigan sumando el alto del retrato:
   27.0 + 28.9 + 17.7 = 73.6. */
@media (max-width: 21.5rem) {
  .rail__tag { font-size: 0.8rem; }
  .rail__logo { width: 4.22rem; }
}




/* ---------- 19. Accessibility + print ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  .rail__nav, .hero__cta, .form, .skip { display: none; }
  .shell { display: block; padding: 0; }
  body { font-size: 11pt; }
  a { color: var(--ink); }
}
