/* Portfolio shelves — hand-authored, not generated.

   php/_portfolio.php replaces the export's two placeholder panels with category
   shelves built from YouTube links; this is what draws them. It reproduces the
   inline styles the export wrote into the markup, so the cards look the same as
   before, and adds what the export never had: real thumbnails, hover states,
   and a two-up phone layout for the shorts. Lives outside css/portfolio.css so
   a re-export cannot take it away. */

/* ---- Panel furniture ---- */

.pe-panel-heading {
  color: var(--text-primary);
  margin: 56px 0 28px;
}

.pe-panel-heading-first {
  margin: 8px 0 8px;
}

.pe-panel-intro {
  color: var(--text-secondary);
  margin: 0 0 40px;
  max-width: 640px;
}

.pe-shelf {
  margin-bottom: 48px;
}

.pe-shelf-head {
  text-align: center;
  margin: 0 0 24px;
}

.pe-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-accent);
  background: #EAF4FF;
  border: 1px solid var(--blue-100);
  padding: 7px 16px;
  border-radius: 999px;
}

.pe-chip::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--blue-500);
}

/* ---- Shared card chrome ---- */

.pe-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pe-play > span {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.25s var(--ease-out), background 0.25s var(--ease-out);
}

.pe-play > span::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 15px solid var(--blue-600);
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
  margin-left: 4px;
}

a:hover > .pe-vid-thumb .pe-play > span,
a:hover > .pe-short-thumb .pe-play > span {
  background: #fff;
  transform: scale(1.08);
}

.pe-badge {
  position: absolute;
  left: 10px;
  bottom: 10px;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 999px;
}

.pe-dur {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12px;
  padding: 2px 7px;
  border-radius: 5px;
}

.pe-dur-lg {
  right: 14px;
  bottom: 14px;
  font-size: 13px;
  padding: 3px 8px;
  border-radius: 6px;
}

/* Only an administrator sees these; to everyone else an empty slot is just a
   gradient tile. */
.pe-slot-hint {
  margin-top: 8px;
  font-family: var(--font-body);
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-secondary);
  opacity: 0.75;
  text-align: center;
}

/* ---- Autoplaying players ----

   A card whose thumbnail is a live player: the iframe fills the tile exactly
   where the still would have been, so the 16:9 and 9:16 boxes below still own
   the geometry. Such a card is a <div> rather than an <a> — the iframe eats the
   clicks — so the link moved into the title, and these two rules keep it
   looking like the plain text it replaced. */

.pe-embed {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.pe-vid-title a,
.pe-short-title a {
  color: inherit;
  text-decoration: none;
}

.pe-vid-title a:hover,
.pe-short-title a:hover {
  color: var(--blue-600);
}

/* ---- Long-form: two 16:9 cards per shelf ---- */

.pe-vid-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  max-width: 900px;
  margin: 0 auto;
}

.pe-vid {
  display: block;
  background: var(--white);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

a.pe-vid {
  transition: transform 0.25s var(--ease-out), box-shadow 0.25s var(--ease-out);
}

a.pe-vid:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.13);
}

.pe-vid-thumb {
  position: relative;
  aspect-ratio: 16 / 9;
}

.pe-vid-thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pe-vid-meta {
  padding: 16px;
}

.pe-vid-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.35;
  color: var(--text-primary);
  margin-bottom: 8px;
}

.pe-vid-sub {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--text-secondary);
}

/* ---- Shorts: three 9:16 cards per shelf ---- */

.pe-shorts-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  max-width: 806px;
  margin: 0 auto;
}

.pe-short {
  display: block;
}

.pe-short-thumb {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.pe-short-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pe-short-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text-primary);
  margin-top: 10px;
  line-height: 1.35;
  text-align: center;
}

a.pe-short:hover .pe-short-title {
  color: var(--blue-600);
}

/* ---- Featured edit ---- */

.pe-featured {
  background: var(--surface-dark);
  border-radius: var(--radius-xl);
  overflow: hidden;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  align-items: stretch;
}

.pe-feat-media {
  position: relative;
  /* The frame owns its shape. Without this the grid's align-items: stretch
     sized this column to the height of the copy beside it, leaving a box
     nearer 2:1 than 16:9 — and object-fit: cover paid for the difference by
     shaving the top and bottom off the thumbnail. align-self keeps the stretch
     off this one cell so the ratio is what decides the height; the body cell
     still stretches, so the dark panel stays flush with the image. */
  aspect-ratio: 16 / 9;
  align-self: start;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pe-feat-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.play-lg > span {
  width: 0;
  height: 0;
  border-left: 22px solid var(--blue-600);
  border-top: 14px solid transparent;
  border-bottom: 14px solid transparent;
  margin-left: 6px;
}

.pe-feat-body {
  padding: 36px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.pe-feat-eyebrow {
  color: var(--blue-300);
  margin-bottom: 14px;
}

.pe-feat-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 24px;
  line-height: 1.25;
  color: #fff;
  margin: 0 0 20px;
}

.pe-feat-channel {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
}

.pe-feat-avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: linear-gradient(135deg, #3B82F6, #8AC2FF);
  flex-shrink: 0;
  overflow: hidden;
}

/* A channel avatar fills the disc when there is one; the gradient above shows
   through when there is not. Channel art is square with its own corners — the
   Jancy one is a ring on white — so the circular mask is what makes it read as
   an avatar rather than a pasted square. */
.pe-feat-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.pe-feat-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15.5px;
  color: #fff;
}

.pe-feat-subs {
  display: block;
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.55);
}

.pe-feat-stats {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.pe-feat-stat {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 24px;
  color: #fff;
}

.pe-feat-stat-label {
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.55);
}

.pe-featured .pe-slot-hint {
  color: rgba(255, 255, 255, 0.6);
  text-align: left;
  margin-top: 14px;
}

/* ---- Placeholder gradients, for slots with no video yet ---- */

.pe-ph-1 { background: linear-gradient(135deg, #2563EB, #8AC2FF); }
.pe-ph-2 { background: linear-gradient(135deg, #1D4ED8, #3B82F6); }
.pe-ph-3 { background: linear-gradient(135deg, #3B82F6, #B3D9FF); }
.pe-ph-4 { background: linear-gradient(135deg, #0F172A, #2563EB); }

/* ---- Responsive ----

   The shorts drop to two across on a phone rather than one: three 9:16 tiles
   in a 340px column are unreadable, one is a full screen of scrolling per
   clip. A shelf holding an odd number leaves the last tile centred on its own
   row instead of stranded at the left edge. */

@media (max-width: 820px) {
  .pe-feat-body { padding: 28px; }
}

@media (max-width: 720px) {
  .pe-shorts-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }

  .pe-shorts-row > .pe-short:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    width: calc(50% - 7px);
    margin: 0 auto;
  }

  .pe-short-title { font-size: 13px; }
}

@media (max-width: 560px) {
  .pe-vid-row {
    grid-template-columns: 1fr;
  }

  .pe-panel-heading { margin: 40px 0 24px; }
}

/* ---- Stand-in for a shelf set that cannot be filled yet ----

   Quiet on purpose: this sits under the featured edit and is a status line,
   not something that should compete with it. Dashed rather than solid so it
   reads as a space held open rather than a finished card. */

.pe-more-soon {
  margin-top: 40px;
  padding: 40px 28px;
  background: var(--surface-alt);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-xl);
  text-align: center;
}

.pe-more-soon-eyebrow {
  color: var(--text-accent);
  margin-bottom: 10px;
}

.pe-more-soon p {
  color: var(--text-secondary);
  max-width: 460px;
  margin: 0 auto;
}

@media (max-width: 600px) {
  .pe-more-soon { padding: 30px 20px; }
}
