/* ============================================================
   Portfolio — Emmanuel Nguyen
   Exploration — one log, read from end to end.

   The third face of the section: exploration-map.css draws the sky,
   exploration-feed.css the list, this one the document. It is the
   only one of the three that is pure reading, so everything here
   serves a single 680px column — the rail on its left is an
   instrument panel, not a second column of content.

   The page is also a template: the generator fills it from the
   markdown. Every block styled here is a block the model allows,
   and the model allows nothing that is not styled here.
   ============================================================ */

/* ---------- The log's colour ----------
   A log wears its constellation's neon, the same the list and the
   map give it. Declared once on the page and read everywhere below:
   five selectors repeated per component is how two places end up
   saying two different colours. */

.ent { --pal: var(--acc); }
.ent[data-pal="magenta"] { --pal: #ff3df0; }
.ent[data-pal="lime"]    { --pal: #a8ff2e; }
.ent[data-pal="ice"]     { --pal: #2f8bff; }
.ent[data-pal="ember"]   { --pal: #ffc21a; }

/* ---------- Frame ----------
   Not the site's two-column grid: a reading page is one column, and
   the rail rides beside it rather than splitting the page in two.
   The pair is centred, so the text sits where the eye rests rather
   than against the left edge. */

.ent__wrap {
  display: flex;
  justify-content: center;
  gap: 56px;
  padding: 96px var(--pad) 110px;
}

.ent__col {
  width: 680px;
  max-width: 100%;
  flex-shrink: 0;
}

/* ---------- The technical rail ----------
   It carries what the front matter carries, and nothing else. It
   stays in view while the text scrolls: its job is to answer "what
   am I reading" at any point, not only at the top. */

.ent__rail {
  width: 176px;
  flex-shrink: 0;
}

.ent__rail-in {
  position: sticky;
  top: 108px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.ent__row { display: grid; gap: 6px; justify-items: start; }

/* One hairline, under the identity: it separates who this log is
   from what it is made of. More rules and the rail becomes a table. */
.ent__hr {
  height: 1px;
  background: var(--line-soft);
}

/* The rail's own label/value pair. Smaller and dimmer than the
   site's .label, which is sized for section headings. */
.ent__label {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 1px;
  color: var(--txt-4);
}

.ent__val {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  color: var(--txt-2);
}

/* The number wears the constellation, here as in the list: the same
   #001 cannot be cyan on one page and magenta on the next. */
.ent__id {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 1px;
  color: var(--pal);
}

/* The theme reads as it does in the list: its astre, then its name.
   The dot is defined here rather than borrowed from the map, so an
   article page never has to load the map's stylesheet. */
.ent__theme { display: flex; align-items: center; gap: 8px; }

.ent__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--pal);
}

/* Stacked, not in a row: 176px fits one chip, and a wrapped row of
   chips would read as a paragraph. */
.ent__tags { flex-direction: column; align-items: start; }

/* ---------- Head ---------- */

.ent__head { display: flex; flex-direction: column; gap: 20px; }

/* The site's .h1 sets caps, which suits a page name (PROJETS, EXPLORATION).
   A log's title is a sentence, and a sentence in caps at this size is
   read letter by letter. */
.ent__title {
  text-transform: none;
  font-size: 56px;
  line-height: 1.15;
  letter-spacing: -1px;
  min-height: 0;
}

/* The chapô is the front matter's, not a first paragraph: a step
   above the body, a step below the title, and it never repeats. */
.ent__chapo {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
  color: var(--txt-3);
}

/* ---------- The five blocks ----------
   Paragraph, ##, ###, quote, media — the five that
   content/exploration/_modele-log.md allows. A sixth would have to
   be added here before it could be written there. */

.ent__body { padding-top: 56px; }

.ent__body p {
  margin: 0 0 26px;
  font-size: var(--fs-md);
  line-height: var(--lh-md);
  color: var(--txt-2);
}
.ent__body > *:last-child { margin-bottom: 0; }

/* The one mark allowed inside a sentence, and it speaks in amber —
   the site's second accent, kept for what is happening rather than
   what is linked. Cyan would have made emphasis look like a link in
   a body of text that holds none. */
.ent__body strong {
  font-weight: 600;
  color: var(--acc2);
}

.ent__body h2 {
  margin: 56px 0 26px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 32px;
  line-height: 1.2;
  color: var(--txt);
}
.ent__body h3 {
  margin: 44px 0 20px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 24px;
  line-height: 1.25;
  color: var(--txt);
}
/* A heading that opens the document has nothing to breathe away from. */
.ent__body > h2:first-child,
.ent__body > h3:first-child { margin-top: 0; }

/* A breath, not a box: one rule and a step up in size. It keeps the
   site's cyan rather than the log's colour — every log quotes the
   same way, and the constellation is already said three times above. */
.ent__quote {
  margin: 44px 0;
  padding: 6px 0 6px 26px;
  border-left: 2px solid var(--acc);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  line-height: 1.5;
  color: var(--txt);
}
.ent__quote p { margin: 0; font: inherit; color: inherit; }

/* ---------- Press ----------
   A mention somewhere else. The site embeds no third party — an
   iframe calls someone else's server before the reader has asked for
   anything — so the card is typographic and sends you to the source,
   which is also the honest treatment for a video that is not yours. */

/* The run of cards carries the spacing, not each card: a block of
   rules needs air around it, and more of it after than before —
   every other block of the body keeps its own space below, so
   nothing separated the last card from the text that followed. */
/* The rules stop where the text does — nothing in the body reaches
   past the reading column. The padding is taken inside instead, so a
   lit row breathes around its title and the title sits in from the
   rule rather than under its end. */
.ent__press-group { margin: 32px 0 48px; }

.ent__press {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 20px 24px;
  border-top: 1px solid var(--line-soft);
  color: var(--txt);
}
/* Last of the run, by position: :last-of-type counted <a> elements,
   and would have closed the wrong row the day a link appeared
   anywhere else in the body. */
.ent__press:last-child { border-bottom: 1px solid var(--line-soft); }
.ent__press:hover { background: var(--row-hover); color: var(--txt); }

.ent__press-text { display: grid; gap: 6px; flex: 1 1 auto; }

.ent__press-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  line-height: 1.35;
}

.ent__press-src {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  color: var(--txt-4);
}

.ent__press-go { flex: 0 0 auto; color: var(--acc); }

/* ---------- Media ----------
   Bounded to the reading measure: a media wider than the text makes
   every image a new beginning. width and height are written by the
   generator from the file itself, so nothing moves as it loads. */

.ent__fig { margin: 48px 0 0; display: flex; flex-direction: column; gap: 12px; }
.ent__fig + p,
.ent__fig + h2,
.ent__fig + h3 { margin-top: 48px; }

.ent__fig img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line-soft);
  background: var(--bg-panel);
}

/* A clip wears the dossiers' .feat__media whole — its frame, its
   corner brackets, its play control, its zoom. The ratio is written
   on the element by the generator, read from the file itself, so the
   frame has its height before a byte of video arrives. */

.ent__cap {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.5;
  color: var(--txt-4);
}

/* ---------- Same orbit ----------
   Only logs of this constellation: it is an orbit, not an archive.
   A log alone in its theme gets no block at all — the generator
   leaves it out rather than printing a heading over nothing. */

.ent__orbit {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-top: 64px;
}

.ent__orbit-head { display: flex; flex-direction: column; align-items: start; }

.ent__orbit-kicker {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 2px;
  color: var(--txt-4);
}

.ent__orbit-theme {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 16px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 2px;
  color: var(--pal);
}

/* A row: number, title, reading time. The middle column takes what
   the other two leave, so the time stays flush right whatever the
   title's length. */
.ent__sib {
  display: flex;
  align-items: baseline;
  gap: 20px;
  /* The same inset as a press card: both are rows you can light up,
     and they sit a few centimetres apart. */
  padding: 18px 24px;
  border-top: 1px solid var(--line-soft);
  color: var(--txt);
}
.ent__sib:last-child { border-bottom: 1px solid var(--line-soft); }
.ent__sib:hover { background: var(--row-hover); color: var(--txt); }

.ent__sib-id {
  width: 96px;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  letter-spacing: 1px;
  color: var(--pal);
}

.ent__sib-title {
  flex: 1 1 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  line-height: 1.35;
}

.ent__sib-time {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 16px;
  color: var(--txt-4);
}

/* Cookie settings, reachable from every page of the site. */
.ent__foot { margin: 0; padding: 28px var(--pad) 48px; }

/* ---------- Narrow ----------
   Under 1100px the rail has no room beside the column. It goes on
   top, laid out as one line of instruments — which is what it has
   been all along. */

@media (max-width: 1100px) {
  .ent__wrap {
    flex-direction: column;
    align-items: center;
    gap: 40px;
    padding-top: 64px;
  }

  .ent__rail { width: 680px; max-width: 100%; padding-top: 0; }
  .ent__rail-in {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: start;
    gap: 16px 40px;
  }
  /* A vertical hairline would have no height in a row, and the row
     no longer needs one to be read. */
  .ent__hr { display: none; }
  .ent__tags { flex-direction: row; }
}

@media (max-width: 720px) {
  .ent__wrap { padding: 48px var(--pad) 72px; gap: 32px; }
  .ent__title { font-size: 34px; letter-spacing: 0; }
  .ent__chapo { font-size: var(--fs-md); line-height: var(--lh-md); }
  .ent__body { padding-top: 36px; }
  .ent__body h2 { margin: 44px 0 20px; font-size: 26px; }
  .ent__body h3 { margin: 32px 0 16px; font-size: 20px; }
  .ent__quote { margin: 32px 0; padding-left: 20px; font-size: 21px; }
  .ent__fig { margin-top: 36px; }
  .ent__orbit { padding-top: 48px; }
  .ent__sib { flex-wrap: wrap; gap: 6px 20px; }
  .ent__sib-title { flex: 1 1 100%; order: 3; }
}
