/* ryanoprea.com
   Rebuilt to match the Google Sites original's measured metrics exactly.
   Every number below was read off the live site at 1280px and 375px.

   The one intentional departure: links are not underlined.
   Paper titles keep their underline.

   The typographic idea being preserved: very large EB Garamond display type
   against 12px Merriweather set on 19.2px leading. The tiny type on generous
   leading is what makes the text blocks read as texture rather than as copy.
*/

:root {
  --ink:   #000;
  /* The original hue, darkened 7%. 4.53:1 on white and 4.64:1 against the black
     body text, so links clear WCAG AA and stay separable from body copy. This is
     as vibrant as a red can be and still pass: #ff0000 itself measures 4.00:1 on
     white, which fails at this text size. */
  --red:   #ee0000;
  --paper: #fff;
  --display: "EB Garamond", Georgia, "Times New Roman", serif;
  --text:    "Merriweather", Georgia, "Times New Roman", serif;

  /* Measured column geometry. Between 768px and 1280px the whole block is
     fluid; above 1280px it caps. Column proportions are near-constant. */
  --content-w:  min(935px, calc(95vw - 60px));
  --col-gap:    clamp(33px, 3.5vw, 45px);

  /* The masthead keeps the 346px measure the left column has always had, while
     the working papers below it run the full column. Two separate knobs:
     --masthead-w governs the top of the page, --content-w governs the lists. */
  --masthead-w: 346px;

  /* Display type. Google Sites sets these in points across four bands;
     the px values below are those points x 4/3. Line-heights are ratios,
     which hold exactly at every band. Band values are at the bottom of the file. */
  /* The name is a fixed multiple of the role beneath it, at every width.
     56pt / 26pt = 28/13 = 2.153846, the ratio the desktop layout has always had.
     Google Sites did not hold it: the name fell to 1.81x on phones and 2.00x on
     tablets, so the composition was subtly different on every screen. Setting the
     name from the role keeps one composition everywhere. Retune here, once. */
  --name-ratio:  2.153846;
  --name-size:   calc(var(--role-size) * var(--name-ratio));

  --role-size:   34.6667px;   /* 26pt - role and section headings share a size */
  --h2-size:     34.6667px;   /* 26pt */
  --addr-size:   26.6667px;   /* 20pt */

  /* "ryan oprea" is 4.0211 x its font-size wide in EB Garamond, so it fits its
     column at 24.87% of the column width. 24.4% leaves a little slack. The min()
     keeps the measured size wherever it already fits and only shrinks the name
     in the 768-1140px range, where it would otherwise break onto two lines. */
  --name-fit: 24.4cqw;

  --name-lh:  1.2;
  --role-lh:  0.96;
  --h2-lh:    1.2;
  --addr-lh:  1.08;

  /* body type — identical at every width, as on the original */
  --body-size:   12px;
  --service-size:13px;
  --body-lh:     19.2px;

  /* measured vertical rhythm */
  --gap-a:       18px;   /* name->role, bio->vita, address->contact, h2->list */
  --gap-b:       19px;   /* role->bio, vita->address, between service items */
  --gap-break:   37px;   /* contact -> section heading */
  --top-pad:     92px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: var(--body-size);
  line-height: var(--body-lh);
}

.wrap {
  width: var(--content-w);
  margin: 0 auto;
  padding: var(--top-pad) 0 120px;
}

.grid {
  display: grid;
  /* 45/55, not 50/50. The right-hand column carries the work that should read
     first, so it gets the greater width. It also shortens the overhang of the
     left column's lists past the masthead (346px) from 99px to 55px. */
  grid-template-columns: 45fr 55fr;
  column-gap: var(--col-gap);
  align-items: start;
}

/* Two grid children: column one holds the masthead with the lower-priority
   sections beneath it, column two holds working papers and the main
   publication sections, so "working papers" starts level with the name.
   No row spanning -- a spanning item distributes its height across both rows
   and pushes the lower-left sections hundreds of pixels down the page. */

/* ---------- left column ---------- */

/* the name sizes itself against the masthead, not the viewport */
.masthead { container-type: inline-size; }

.name {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--name-size);                        /* fallback */
  font-size: min(var(--name-size), var(--name-fit));  /* never wraps */
  line-height: var(--name-lh);
  margin: 0;
}

.role {
  font-family: var(--display);
  font-size: var(--role-size);
  line-height: var(--role-lh);
  margin: var(--gap-a) 0 0;
}

.bio p {
  margin: var(--gap-b) 0 0;
}
.bio p + p { margin-top: var(--gap-a); }

.address {
  font-family: var(--display);
  font-size: var(--addr-size);
  line-height: var(--addr-lh);
  margin: var(--gap-b) 0 0;
}
.address + .address { margin-top: var(--gap-a); }

/* the masthead keeps its narrow measure once the columns are side by side */
@media (min-width: 768px) {
  .masthead { max-width: var(--masthead-w); }
}

/* ---------- headings ---------- */

h2 {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--h2-size);
  line-height: var(--h2-lh);
  margin: 0;
}

/* Each publication group is a <section> so it can be ordered independently
   when the page stacks. Spacing is by position, not by which column it is in. */
section > h2                          { margin-top: 16px; }
.masthead + section > h2              { margin-top: var(--gap-break); }
.col-right > section:first-child > h2 { margin-top: 22px; }

/* ---------- lists ---------- */

ul { list-style: none; margin: 0; padding: 0; }

.service { margin-top: var(--gap-a); }
.service li { font-size: var(--service-size); }
.service li + li { margin-top: var(--gap-b); }

.papers { margin-top: 30px; }
.papers li + li { margin-top: 16px; }

/* a paper title: underlined, and not a link */
.t { text-decoration: underline; text-underline-offset: 1px; }

/* journal or outlet name */
.j { font-weight: 700; }

/* italic asides: "revising for", "previously circulated as", prizes */
.aside { font-style: italic; }

.tag { white-space: nowrap; }

/* the Banki reply sits indented under its parent entry */
.sub { display: block; margin-left: 20px; }

/* ---------- links ---------- */

a { color: var(--red); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; text-underline-offset: 1px; }
a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

/* ---------- responsive bands ----------
   Taken from Google Sites' own media queries:

                       <=479px   480-767px   768-1279px   >=1280px
     role / heading     21pt       24pt         26pt         26pt
     address            18pt       19pt         20pt         20pt
     body copy          12px       12px         12px         12px

   The name is not listed because it is no longer set per band: it is always
   2.153846x the role size, so it follows the row above. Google Sites used
   38/48/56pt here, which made the name proportionally smaller on small screens.

   The columns stack below 768px, not below 900px.
   Body copy never changes size at any width.
*/

/* stacked: everything below 768px.
   Order is deliberate — masthead, then working papers and the main publication
   sections, then the remaining sections. Putting the left-hand lists last keeps
   the working papers near the top on a phone, where there is no second column
   to hold them. */
@media (max-width: 767px) {
  /* align-items:start from the grid rule would make every block shrink to fit
     in a column flex container, and with container-type on the masthead that
     resolves to zero width. Stretch them back to the full content width. */
  .grid { display: flex; flex-direction: column; align-items: stretch; }
  /* dissolve the column-one wrapper so its two children can be ordered
     independently against the right-hand column */
  /* dissolve both columns so every section can be ordered on its own merits */
  .col-one, .col-right { display: contents; }

  /* Reading priority when there is only one column. This is the hierarchy the
     page asserts: current work first, then the two main research programmes,
     then the market work, then the smaller groupings. */
  .masthead       { order: 0; }
  #sec-working    { order: 1; }
  #sec-complexity { order: 2; }
  #sec-continuous { order: 3; }
  #sec-market     { order: 4; }
  #sec-beliefs    { order: 5; }
  #sec-learning   { order: 6; }
  #sec-other      { order: 7; }

  /* spacing follows visual position, so reset the DOM-adjacency rules above */
  section > h2             { margin-top: 16px; }
  .masthead + section > h2 { margin-top: 16px; }
  /* 93px here reproduced the old Google Sites gap; Ryan found it too big a
     hole between the contact block and the first heading. --gap-break (37px)
     is the spacing the site already uses between the contact block and a
     section heading in the two-column layout, so it matches the rest. */
  #sec-working > h2        { margin-top: var(--gap-break); }
}

/* small tablet / narrowed window */
@media (min-width: 480px) and (max-width: 767px) {
  :root {
    --role-size: 32px;        /* 24pt -> name 68.9px */
    --h2-size:   32px;        /* 24pt */
    --addr-size: 25.3333px;   /* 19pt */
    --content-w: min(491px, calc(100vw - 49px));  /* the original caps here too */
    --top-pad:   77px;
  }
}

/* phone */
@media (max-width: 479px) {
  :root {
    --role-size: 28px;        /* 21pt -> name 60.3px */
    --h2-size:   28px;        /* 21pt */
    --addr-size: 24px;        /* 18pt */
    --content-w: auto;
    --top-pad:   62px;
  }
  .wrap { padding-left: 27px; padding-right: 27px; }
}

/* ---------- print ---------- */

@media print {
  .wrap { max-width: none; padding: 0; }
  .grid { grid-template-columns: 1fr; }
  a { color: #000; }
}
