/* ===========================================================================
   LE PORTANT — the collection as a rail the house re-hangs.

   There are no cards on this page. A card is a container that says "this thing
   is separate". A rail says the opposite: these pieces are hung together, and
   which ones hang together is the thing the visitor changes.

   So the only drawn lines are the rails themselves — one continuous hairline
   across each row, with a short hook dropping from it to every garment. The
   garment sits on the paper with nothing around it. Everything else is type.

   Built on the Concept C tokens and the fiche's key/value grammar. It adds no
   colours and no fonts.
   =========================================================================== */

:root {
  --pt-hook: 15px;   /* the drop from the rail to the top of a garment */
}

.pt { padding-bottom: clamp(56px, 8vw, 120px); }

/* ---------------------------------------------------------------------------
   1. HEAD — the tally is the only instruction on the page, and it is a fact
   ------------------------------------------------------------------------ */

.pt-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4, 16px);
  padding-block: var(--sp-5, 20px) var(--sp-6, 24px);
}

.pt-title {
  font-family: var(--cc-display);
  font-size: clamp(38px, 6vw, 84px);
  line-height: 0.95;
  letter-spacing: -0.03em;
  margin: 0;
}

/* "8 pièces · 20 accrochages". The first number never moves. The second one
   does, and that is the page explaining itself without a sentence. */
.pt-tally {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin: 0;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  color: var(--cc-muted);
  font-variant-numeric: tabular-nums;
}
.pt-tally b {
  font-size: 15px;
  letter-spacing: 0;
  color: var(--cc-ink);
  font-weight: 600;
}
.pt-tally i { font-style: normal; color: var(--cc-muted); }

/* ---------------------------------------------------------------------------
   2. CONSOLE — how the rail gets hung
   ------------------------------------------------------------------------ */

.pt-console {
  display: grid;
  gap: var(--sp-5, 20px);
  padding-block: var(--sp-5, 20px);
  border-block: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
}
@media (min-width: 900px) {
  .pt-console {
    grid-template-columns: minmax(0, auto) minmax(0, auto) minmax(200px, 1fr) auto;
    gap: clamp(24px, 3vw, 56px);
    align-items: start;
  }
}

.pt-console fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

.pt-legend {
  display: block;
  padding: 0 0 10px;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  color: var(--cc-muted);
}

.pt-axes__row, .pt-sizes__row { display: flex; flex-wrap: wrap; gap: 4px 0; }

/* The axis names are set in the display face, because choosing an axis is the
   page's main verb and it should read like a heading, not like a form. */
.pt-axis, .pt-size {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  padding-inline: 12px;
  cursor: pointer;
  color: var(--cc-muted);
  transition: color var(--cc-fast) var(--cc-ease);
}
.pt-axis:first-child, .pt-size:first-child { padding-inline-start: 0; }

.pt-axis input, .pt-size input {
  position: absolute;
  inline-size: 1px; block-size: 1px;
  opacity: 0;
  margin: 0;
}
.pt-axis > span {
  font-family: var(--cc-display);
  font-size: clamp(19px, 2vw, 26px);
  line-height: 1;
  letter-spacing: -0.01em;
}
.pt-size > span {
  font-size: 13px;
  letter-spacing: 0.04em;
  min-inline-size: 1.6em;
  text-align: center;
}

.pt-axis:hover, .pt-size:hover { color: var(--cc-ink); }
.pt-axis:has(input:checked), .pt-size:has(input:checked) { color: var(--cc-ink); }

/* The chosen axis is underscored by the rail's own hairline, so the control
   and the thing it controls are drawn with the same line. */
.pt-axis:has(input:checked)::after,
.pt-size:has(input:checked)::after {
  content: "";
  position: absolute;
  inset-inline: 12px;
  inset-block-end: 6px;
  block-size: 2px;
  background: var(--cc-ink);
}
.pt-axis:first-child:has(input:checked)::after,
.pt-size:first-child:has(input:checked)::after { inset-inline-start: 0; }

.pt-axis:has(input:focus-visible),
.pt-size:has(input:focus-visible) {
  outline: 2px solid var(--cc-ink);
  outline-offset: 2px;
}

.pt-find { min-width: 0; }
.pt-find__input {
  inline-size: 100%;
  min-block-size: 44px;
  padding: 0 0 8px;
  border: 0;
  border-bottom: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
  background: transparent;
  color: var(--cc-ink);
  font: inherit;
  font-size: 15px;
}
.pt-find__input::placeholder { color: var(--cc-faint); }
.pt-find__input:focus-visible {
  outline: none;
  border-bottom-color: var(--cc-ink);
  box-shadow: 0 1px 0 var(--cc-ink);
}

.pt-console__end {
  display: flex;
  align-items: end;
  gap: var(--sp-4, 16px);
  align-self: end;
}

/* The submit button exists for a page without a script; with one, the rail
   re-hangs the moment an axis changes and the button would be a lie. */
html.js .pt-apply { display: none; }

.pt-viewlink {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-block-size: 44px;
  color: var(--cc-muted);
  text-decoration: none;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  white-space: nowrap;
}
.pt-viewlink:hover { color: var(--cc-ink); }

/* ---------------------------------------------------------------------------
   3. ACTIVE CONDITIONS — always stated, always removable
   ------------------------------------------------------------------------ */

.pt-active {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px var(--sp-4, 16px);
  padding-block: 14px;
  border-block-end: 1px solid var(--fi-rule, rgba(17, 17, 17, 0.14));
}
.pt-active .pt-legend { padding: 0; }
.pt-active__list { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }

.pt-active__list button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 32px;
  padding-inline: 10px;
  border: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
  background: transparent;
  color: var(--cc-ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  transition: background var(--cc-fast) var(--cc-ease);
}
.pt-active__list button:hover { background: var(--cc-bone); }
.pt-active__list button::after { content: "×"; font-size: 15px; line-height: 1; color: var(--cc-muted); }

.pt-clear {
  display: inline-flex;
  align-items: center;
  min-block-size: 40px;
  background: none;
  border: 0;
  padding: 4px 0;
  font: inherit;
  font-size: 12px;
  color: var(--cc-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.pt-clear:hover { color: var(--cc-burgundy); }

/* ---------------------------------------------------------------------------
   4. THE RAILS
   ------------------------------------------------------------------------ */

.pt-rails { display: grid; }
.pt-rail { padding-block: clamp(28px, 4vw, 52px) 0; }

.pt-rail__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4, 16px);
  margin: 0 0 var(--pt-hook);
  padding-bottom: 10px;
}
.pt-rail__name {
  font-family: var(--cc-display);
  font-size: clamp(26px, 3.4vw, 44px);
  line-height: 1;
  letter-spacing: -0.02em;
}
.pt-rail__count {
  flex: none;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  color: var(--cc-muted);
  font-variant-numeric: tabular-nums;
}
.pt-rail__count b { color: var(--cc-ink); font-weight: 600; }

/* The rail itself. Each piece carries the hairline above it, so a row of
   pieces draws one continuous line and a rail that wraps draws a second one —
   which is exactly what happens when a shop runs out of rail. */
.pt-hangs {
  position: relative;
  display: grid;
  /* Every garment on the page is the same size, whichever rail it hangs on,
     because the point of a rail is that you can compare what is on it. How big
     a group is gets said in type — the rail's own count — not by inflating its
     photographs. */
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A rail with two garments on it is still a rail across the whole wall. The
   pieces draw the hairline for the rows they fill; this draws the first one
   edge to edge regardless. */
.pt-hangs::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 1px;
  background: var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
}

.pt-piece {
  position: relative;
  border-top: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
  padding: var(--pt-hook) var(--sp-4, 16px) var(--sp-6, 24px) 0;
  transition: opacity var(--cc-state) var(--cc-ease);
}

/* The hook: the garment hangs from the rail rather than sitting under it. */
.pt-piece::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 1px;
  block-size: var(--pt-hook);
  background: var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
}

.pt-piece__link {
  display: grid;
  gap: 10px;
  color: inherit;
  text-decoration: none;
}

.pt-piece__hang {
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--cc-bone);
}
.pt-piece__hang img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--cc-reveal) var(--cc-ease);
}
.pt-piece__nophoto { display: block; block-size: 100%; }

@media (hover: hover) and (pointer: fine) {
  .pt-piece__link:hover .pt-piece__hang img { transform: scale(1.035); }
}

.pt-piece__record {
  display: grid;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}
.pt-piece__name {
  font-size: 14px;
  line-height: 1.3;
  text-wrap: pretty;
}
.pt-piece__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--cc-muted);
}
.pt-piece__meta b { font-weight: 400; color: var(--cc-ink); unicode-bidi: isolate; }
.pt-piece__price { font-size: 13px; }
.pt-piece__price s { color: var(--cc-muted); margin-inline-start: 6px; font-size: 11px; }

.pt-piece__link:focus-visible { outline: 2px solid var(--cc-ink); outline-offset: 4px; }

/* --- the note line: why this piece is marked, in words --- */

.pt-piece__note {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.04em;
  color: var(--cc-muted);
  min-block-size: 1.4em;      /* reserved, so marking a piece never reflows */
}
.pt-piece__note:empty::after { content: ""; }

/* --- states --- */

/* Declared a size that this piece does not run in. It stays on the rail and
   says so, because "we do not have your size" is information, and removing it
   would be the shop pretending the piece is not there. */
/* The garment recedes; the sentence explaining why does not. Fading the note
   along with the picture would drop the one thing the visitor needs to read
   below a legible contrast. */
.pt-piece[data-runs="false"] .pt-piece__link { opacity: 0.4; }
.pt-piece[data-runs="false"] .pt-piece__note { color: var(--cc-ink); }

/* The same piece, hanging on another rail. Only ever shown as a response to
   the visitor pointing at or focusing one of its hangings. */
.pt-piece[data-echo="true"]::after {
  content: "";
  position: absolute;
  inset-block-start: -1px;
  inset-inline: 0 var(--sp-4, 16px);
  block-size: 2px;
  background: var(--cc-ink);
}
.pt-piece[data-kin="true"]::after {
  content: "";
  position: absolute;
  inset-block-start: -1px;
  inset-inline: 0 var(--sp-4, 16px);
  block-size: 2px;
  background: var(--cc-burgundy);
}
.pt-piece[data-kin="true"] .pt-piece__note { color: var(--cc-burgundy); }

.pt-piece[hidden] { display: none; }

.pt-rail[hidden] { display: none; }

.pt-none {
  padding-block: clamp(40px, 7vw, 80px);
  font-size: 15px;
  color: var(--cc-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: baseline;
}

/* ---------------------------------------------------------------------------
   5. THE INDEX — the same rail read as one table
   ------------------------------------------------------------------------ */

.pt-body[data-view="rail"] .pt-index { display: none; }
.pt-body[data-view="index"] .pt-rails,
.pt-body[data-view="index"] .pt-none { display: none; }

.pt-index { padding-block: var(--sp-6, 24px) 0; overflow-x: auto; }

.pt-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}
.pt-table th, .pt-table td {
  text-align: start;
  padding: 13px var(--sp-4, 16px) 13px 0;
  border-bottom: 1px solid var(--fi-rule, rgba(17, 17, 17, 0.14));
  white-space: nowrap;
}
.pt-table thead th {
  border-bottom: 2px solid var(--cc-ink);
  padding: 0 var(--sp-4, 16px) 10px 0;
}
.pt-table thead button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  color: var(--cc-muted);
  cursor: pointer;
  min-block-size: 34px;
}
.pt-table thead button:hover { color: var(--cc-ink); }
.pt-table thead th[aria-sort] button { color: var(--cc-ink); }
.pt-table thead th[aria-sort="ascending"] button::after { content: " ↑"; }
.pt-table thead th[aria-sort="descending"] button::after { content: " ↓"; }

.pt-table tbody th { font-weight: 400; white-space: normal; min-inline-size: 16ch; }
.pt-table tbody th a { color: inherit; text-decoration: none; }
.pt-table tbody th a:hover { text-decoration: underline; text-underline-offset: 3px; }
.pt-table tbody tr:hover { background: var(--cc-bone); }
.pt-table .pt-num { text-align: end; padding-inline-end: 0; }
.pt-table tr[data-runs="false"] th a,
.pt-table tr[data-runs="false"] td { opacity: 0.5; }
.pt-table tr[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   6. PHONES — the same rails, read in sequence
   ------------------------------------------------------------------------ */

@media (max-width: 719px) {
  .pt-console { gap: var(--sp-4, 16px); }
  .pt-console__end { align-self: start; justify-content: space-between; }

  /* The rail's name stays in view while its pieces go past, so the visitor
     always knows which rail they are reading. */
  .pt-rail__head {
    position: sticky;
    inset-block-start: calc(var(--header-h, 64px) - 1px);
    z-index: 2;
    margin-bottom: 0;
    padding-block: 12px;
    background: var(--cc-paper);
    border-bottom: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
  }
  .pt-rail__name { font-size: clamp(22px, 7vw, 30px); }

  /* One piece per line: the garment small and steady on the reading side, the
     record beside it. The hook and the rail hairline are kept, so the page is
     recognisably the same object it is on a laptop. */
  .pt-hangs { grid-template-columns: 1fr; }
  .pt-piece { padding: var(--pt-hook) 0 16px; }
  .pt-piece:first-child { border-top: 0; }
  .pt-piece:first-child::before { display: none; }

  .pt-piece__link {
    grid-template-columns: 84px minmax(0, 1fr);
    gap: 14px;
    align-items: start;
  }
  .pt-piece__name { font-size: 15px; }
  .pt-piece__note { margin-inline-start: 98px; margin-top: 4px; }

  .pt-table th, .pt-table td { padding-inline-end: 14px; }
}

/* ---------------------------------------------------------------------------
   7. MOTION — movement only ever says "the rail was re-hung"
   ------------------------------------------------------------------------ */

@keyframes pt-settle {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.pt-rails[data-rehung="true"] .pt-rail {
  animation: pt-settle 380ms var(--cc-ease) both;
}
.pt-rails[data-rehung="true"] .pt-rail:nth-child(2) { animation-delay: 45ms; }
.pt-rails[data-rehung="true"] .pt-rail:nth-child(3) { animation-delay: 90ms; }
.pt-rails[data-rehung="true"] .pt-rail:nth-child(4) { animation-delay: 130ms; }
.pt-rails[data-rehung="true"] .pt-rail:nth-child(n+5) { animation-delay: 165ms; }

@media (prefers-reduced-motion: reduce) {
  .pt-rails[data-rehung="true"] .pt-rail { animation: none; }
  .pt-piece__hang img, .pt-piece { transition: none; }
}

/* ---------------------------------------------------------------------------
   8. RTL
   ------------------------------------------------------------------------ */

html[dir="rtl"] .pt-piece__meta b,
html[dir="rtl"] .pt-piece__price,
html[dir="rtl"] .pt-table .pt-num { direction: ltr; unicode-bidi: isolate; }
html[dir="rtl"] .pt-table .pt-num { text-align: start; }
html[dir="rtl"] .pt-axis > span { letter-spacing: 0; }
@media (max-width: 719px) {
  html[dir="rtl"] .pt-piece__note { margin-inline-start: 98px; margin-inline-end: 0; }
}

/* The rest of a long rail. It states how many are waiting rather than saying
   "load more", because the number is the useful part. */
.pt-more {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin-top: var(--sp-5, 20px);
  padding: 0 0 4px;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--cc-ink);
  font: inherit;
  font-size: var(--fi-key, 11px);
  letter-spacing: var(--fi-track, 0.15em);
  text-transform: uppercase;
  color: var(--cc-ink);
  cursor: pointer;
  min-block-size: 40px;
}
.pt-more b { font-size: 15px; letter-spacing: 0; }
.pt-more:hover { color: var(--cc-burgundy); border-bottom-color: var(--cc-burgundy); }

/* Every control on this page shows where the keyboard is, including the ones
   drawn as plain text. */
.pt-clear:focus-visible,
.pt-more:focus-visible,
.pt-viewlink:focus-visible,
.pt-active__list button:focus-visible,
.pt-table thead button:focus-visible,
.pt-apply:focus-visible {
  outline: 2px solid var(--cc-ink);
  outline-offset: 3px;
}

/* A rail that gets scrolled to must clear the header stuck above it. */
.pt-rail { scroll-margin-top: calc(var(--header-h, 72px) + 16px); }

/* The note and the keep share one reserved line under the record. */
.pt-piece__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-inline-end: var(--sp-4, 16px);
}
.pt-piece__foot .pt-piece__note { margin-top: 0; }

.pt-save {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  margin-inline-start: auto;
  background: none;
  border: 0;
  padding: 0;
  color: var(--cc-muted);
  cursor: pointer;
  transition: color var(--cc-fast) var(--cc-ease), transform var(--cc-fast) var(--cc-ease);
}
.pt-save:hover { color: var(--cc-ink); }
.pt-save:active { transform: scale(0.92); }
.pt-save[aria-pressed="true"] { color: var(--cc-burgundy); }
.pt-save[aria-pressed="true"] svg { fill: currentColor; }
.pt-save:focus-visible { outline: 2px solid var(--cc-ink); outline-offset: 2px; }

@media (max-width: 719px) {
  .pt-piece__foot { padding-inline-end: 0; }
  .pt-piece__foot .pt-piece__note { margin-inline-start: 98px; }
}

/* Conditions the page arrived with drop by following a link, so they work
   without a script exactly as they do with one. */
.pt-active__list--fixed a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 32px;
  padding-inline: 10px;
  border: 1px solid var(--fi-rule-firm, rgba(17, 17, 17, 0.3));
  color: var(--cc-ink);
  text-decoration: none;
  font-size: 12px;
}
.pt-active__list--fixed a::after { content: "×"; font-size: 15px; color: var(--cc-muted); }
.pt-active__list--fixed a:hover { background: var(--cc-bone); }
.pt-active__list--fixed a:focus-visible { outline: 2px solid var(--cc-ink); outline-offset: 3px; }
