/* =====================================================
   TON Coffee Roastery — CATALOG
   Kahve kataloğu, ürün detay ve karşılaştırma sayfaları yükler:
   product.html · kahveler.html · karsilastir.html
   İçerik: collection page · filter bar · product page ·
           agregatör grid · karşılaştırma tablo ·
           kahveler standalone page · catalog responsive
   Bağımlılık: core.css + layout.css
   ===================================================== */

/* ---- Collection Page ------------------------------ */
.page-header {
  padding-top: calc(var(--nav-h) + 4rem);
  padding-bottom: 3rem;
  padding-left: 2.5rem;
  padding-right: 2.5rem;
  border-bottom: 1px solid var(--border);
}

.page-header__eyebrow {
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1rem;
}

.page-header h1 {
  font-family: var(--font-d);
  font-size: clamp(2.5rem, 5.5vw, 4.5rem);
  font-weight: 900;
  line-height: 1.0;
  letter-spacing: -0.025em;
}

.page-header__sub {
  font-size: 1rem;
  color: var(--cream-dim);
  margin-top: 1rem;
  max-width: 480px;
}

/* Filtre çubuğu = komut satırı (29 Tem).
   Üç sürümün hikâyesi tek yerde dursun:
   (1) tek satır + gizli `overflow-x:auto` → "Tat profili" ve "Sırala" ekran dışında,
       devam ettiğine dair hiçbir işaret yok. Gizli kontrol, uzun çubuktan kötüdür.
   (2) hepsi açık + sarma → hiçbir kontrol kaybolmuyordu ama bedeli ölçüldü:
       masaüstü 212px / dört satır, mobil 713px = ekranın %85'i, ilk kart 1325px aşağıda.
   (3) bugünkü: çubuk yalnız AÇIK OLAN filtreyi yazar (--kavurma=light), seçenek
       listesi flag'e basınca hemen ALTINDA iner. (1)'in derdi geri gelmiyor çünkü
       kaybolan kontrol yok — her eksen kendi değeriyle görünür duruyor; inen şey
       kontrol değil, onun seçenek listesi. Ölçü: masaüstü 40px, mobil ~86px. */
.filter-bar {
  padding: 1.1rem 2.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
}

.fb__cmd {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.fb__pmt {
  font-family: var(--font-m); font-size: 0.78rem;
  color: var(--muted); flex: none; margin-right: 0.1rem;
}

/* Flag = eksenin kendisi. Ana sayfa hero çipiyle AYNI gramer (dolgu + görünür kenar
   + saç teli ayraçtan sonra değer) — iki yüzey aynı aileden okunsun diye. Çubuk
   --bg-2 zemininde durduğu için dolgu bir kademe yukarı (--bg-3). */
.fb__flag {
  display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 34px;
  font-family: var(--font-m); font-size: 0.76rem; letter-spacing: 0.01em;
  text-transform: lowercase;
  color: var(--cream-dim);
  background: var(--bg-3);
  border: 1px solid var(--border-3);
  border-radius: var(--r);
  padding: 0.26rem 0.6rem;
  cursor: pointer;
  transition: border-color var(--dur-2), color var(--dur-2), background var(--dur-2);
}
.fb__flag b {
  font-weight: 400; color: var(--cream);
  padding-left: 0.5rem; border-left: 1px solid var(--border-2);
}
/* ▾ açık panelde ▴ olur: hangi listenin indiği düğmenin kendisinden okunur */
.fb__flag::after {
  content: "▾"; font-size: 0.6em; color: var(--muted); margin-left: -0.15rem;
  transition: color var(--dur-2);
}
.fb__flag:hover { border-color: var(--pop-line-2); color: var(--cream); }
.fb__flag[aria-expanded="true"] {
  border-color: var(--pop-line-2); color: var(--cream); background: var(--bg-card);
}
.fb__flag[aria-expanded="true"]::after { content: "▴"; color: var(--pop); }
/* set edilmiş eksen: değer yeşil → hangi filtrelerin açık olduğu tek bakışta okunur
   (eski çubukta bunu görmek için 23 çipi taramak gerekiyordu) */
.fb__flag.is-set b { color: var(--pop); }
.fb__flag.is-set { border-color: var(--pop-line); }

.fb__reset {
  font-family: var(--font-m); font-size: 0.72rem; text-transform: lowercase;
  color: var(--muted); background: none; border: 0; cursor: pointer;
  padding: 0.3rem 0.2rem; text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: var(--border-3);
  transition: color var(--dur-2);
}
.fb__reset:hover { color: var(--cream); }
.fb__reset[hidden] { display: none; }

/* Seçenek listesi — flag'in altında açılan çıktı bloğu. Kesikli üst çizgi terminal
   grameri: komut satırı üstte, çıktı altında. JS yoksa paneller AÇIK kalır. */
.fb__panel {
  margin-top: 0.85rem; padding-top: 0.85rem;
  border-top: 1px dashed var(--border-2);
}
html.js .fb__panel { display: none; }
html.js .fb__panel.is-open { display: block; }

.filter-group {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Filtre pill → index hero'nun CLI flag chip register'ı (--espresso).
   kahveler = ~/kahve ❯ sorgusunun sonuç ekranı; filtreler = aktif --flag'ler. */
.filter-pill {
  font-family: var(--font-m);
  font-size: 0.74rem;
  letter-spacing: 0.01em;
  text-transform: lowercase;
  padding: 0.36rem 0.72rem;
  border: 1px solid var(--border-2);
  background: none;
  color: var(--cream-dim);
  border-radius: var(--r);
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.25s var(--ease-o), border-color var(--dur-2), color var(--dur-2), background var(--dur-2);
}
.filter-pill::before {
  content: "--";
  color: var(--muted);
  margin-right: 0.12em;
  transition: color var(--dur-2);
}

.filter-pill:hover {
  transform: translateY(-2px);
  border-color: var(--pop-line-2, var(--accent));
  color: var(--cream);
  background: var(--wash-2, color-mix(in srgb, var(--cream) 6%, transparent));
}
.filter-pill:active { transform: translateY(0); }
.filter-pill.active {
  border-color: var(--accent);
  color: var(--cream);
  background: color-mix(in srgb, var(--cream) 6%, transparent);
}
/* aktif = flag "set": -- işareti accent'e döner */
.filter-pill.active::before { color: var(--pop); }
/* çipteki kayıt sayısı: "--dark 24". 5 Ağu'da dört eksene yayıldı ve aktif filtreyle
   hesaplanır oldu (catalog.js pillCounts). Sayı bir SÖZ: tıklarsan liste bu kadar olacak. */
.filter-pill__n { margin-left: 0.45em; color: var(--muted); font-variant-numeric: tabular-nums; }
.filter-pill.active .filter-pill__n { color: var(--cream-dim); }

/* Sıfır çeken seçenek: GİZLENMEZ, sönük ve tıklanamaz kalır. Gizleseydik seçenek
   listesinin boyu her filtrede değişir, mekânsal hafıza çökerdi (--yöntem=türk açıkken
   kavurmanın 7 seçeneğinden 5'i sıfıra düşüyor). Sönük olan da bir cevaptır: "bu eksen
   burada yok" ile "bu eksende sonuç yok" farklı şeyler. */
.filter-pill.is-zero {
  /* KAP OPAKLIĞI KULLANILMAZ. İki tur ölçüldü: `opacity:.38` → metin 1.86:1,
     `opacity:.6` → metin 2.89:1 / sayı 3.38:1. İkisi de AA'nın (4.5:1) altında ve
     ikisinde de aynı hata var — kabı söndürmek, okunması GEREKEN sayıyı da söndürüyor.
     "Devre dışı kontrol muaftır" doğru ama konuyu kaçırıyor: buradaki `0` seçeneğin
     neden ölü olduğunu söyleyen bilginin kendisi. Onun yerine ölülük KENARLIKTAN
     anlatılır (kesik + sönük çizgi), metin okunur kalır. */
  cursor: not-allowed;
  border-style: dashed;                /* renk körü kullanıcı için ikinci kanal */
  border-color: var(--border-3);
  color: var(--muted);
}
.filter-pill.is-zero:hover { transform: none; border-color: var(--border-3); background: none; color: var(--muted); }
.filter-pill.is-zero::before { color: var(--border-3); }
.filter-pill.is-zero .filter-pill__n { color: var(--muted); }

/* Tat ekseninin DIŞ halkası: seçili ana ailenin alt aileleri. Girintili ray, terminalin
   kendi grameri — komut üstte, çıktısı içeriden. Ana halka seçilmeden bu satır hiç yok. */
.filter-group--sub {
  margin-top: 0.55rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--border-2);
}
.filter-group--sub[hidden] { display: none; }
.filter-pill[hidden] { display: none; }

/* Eksenin kaldırma işareti — flag'in içinde, değerin sağında. `temizle` hepsini
   sıfırlar, bu yalnız bu ekseni düşürür. */
.fb__x {
  /* Dokunma hedefi düğmenin TAM boyunca uzanır (34px masaüstü / 40px mobil): 0.15rem
     dolgulu bir <span> WCAG 2.2'nin 24px asgarisinin altında kalıyordu ve hemen yanındaki
     ▾ karetiyle yan yanaydı — kaldırmak isteyen paneli açardı. */
  align-self: stretch;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px;                          /* WCAG 2.2 · 2.5.8 asgari hedef */
  margin: 0 -0.2rem 0 0.1rem; padding: 0 0.35rem;
  border-left: 1px solid var(--border-2);   /* <b>'nin saç teli ayracıyla aynı gramer */
  color: var(--muted); font-size: 0.95em; line-height: 1;
  transition: color var(--dur-2);
}
.fb__flag:hover .fb__x { color: var(--cream); }
.fb__x:hover { color: var(--pop); }

/* Collection grid — 3-col on desktop */
.collection-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  padding: 3rem 2.5rem;
}

/* ---- Product Page --------------------------------- */
.product-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: calc(100dvh - var(--nav-h));
  margin-top: var(--nav-h);
}

.product-gallery {
  position: sticky;
  top: var(--nav-h);
  height: calc(100dvh - var(--nav-h));
  overflow: hidden;
  background: var(--bg-3);
}

.product-gallery__main {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: opacity var(--dur-4);
}

.product-gallery__thumbs {
  position: absolute;
  bottom: 1.5rem;
  left: 1.5rem;
  display: flex;
  gap: 0.625rem;
}

.product-gallery__thumb {
  width: 54px; height: 54px;
  object-fit: cover;
  border: 1px solid var(--border);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity var(--dur-2), border-color var(--dur-2);
  border-radius: var(--r);
}

.product-gallery__thumb.active,
.product-gallery__thumb:hover {
  opacity: 1;
  border-color: var(--accent);
}

.product-info {
  padding: 4rem 3.5rem;
  border-left: 1px solid var(--border);
  overflow-y: auto;
  max-height: calc(100dvh - var(--nav-h));
}

/* .product-info__crumb → core.css'e TAŞINDI (`.kf-crumb` ile ortak seçici).
 * Sebep: iz artık yalnız ürün/marka sayfasında değil, kök sayfalarda da var;
 * catalog.css sozluk/tarifler/hikaye'de yüklü değil. İki kopya tutulmuyor. */

.product-info__region {   /* veri sayfası terminal register — ❯ prompt glifi (inner-hero--kb aynası) */
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-m);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: var(--cream-dim);
  margin-bottom: 0.625rem;
}
.product-info__region::before {
  content: "\276F";            /* ❯ */
  color: var(--pop);
  font-size: 0.9em;
}

.product-info__name {
  font-family: var(--font-d);
  font-size: clamp(1.9rem, 3vw, 2.8rem);
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: 0.5rem;
  /* Kart→ürün morph: kahveler kartı başlığı buraya morph'lar (catalog.js pageswap
     eşleşen kartın .agg-card__name'ine aynı adı verir). reduced-motion → core.css'te
     tüm VT animasyonu kapalı, ad zararsız. Ürün sayfasında tek örnek → çakışma yok. */
  view-transition-name: coffee-hero;
}

.product-info__sub {
  font-size: 0.92rem;
  color: var(--cream-dim);
  font-style: italic;
  margin-bottom: 1.5rem;
}

/* Flavor chips */
.flavor-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.75rem;
}

.flavor-chip {
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--border-2);
  border-radius: 100px;
  color: var(--cream-dim);
}

.product-info__story {
  font-size: 0.93rem;
  color: var(--cream-dim);
  line-height: 1.85;
  margin-bottom: 2rem;
  padding-bottom: 2rem;
  border-bottom: 1px solid var(--border);
}

/* Accordion */
.accordion { margin-bottom: 2rem; }

.accordion-item { border-bottom: 1px solid var(--border); }

.accordion-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 0;
  color: var(--cream);
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: left;
}

.accordion-trigger svg {
  width: 14px; height: 14px;
  flex-shrink: 0;
  transition: transform var(--dur-4) var(--ease);
  color: var(--accent);
}

.accordion-item.open .accordion-trigger svg { transform: rotate(45deg); }

.accordion-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.4s var(--ease-o);
}

.accordion-item.open .accordion-body { max-height: 300px; }

.accordion-inner {
  padding: 0 0 1.5rem;
}

.spec-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1.5rem;
}

.spec-key {
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.spec-val {
  font-size: 0.88rem;
  color: var(--cream-dim);
}

/* Variants */
.variant-block { margin-bottom: 1.5rem; }

.variant-lbl {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

.variant-lbl strong { color: var(--cream); font-weight: 400; }

.variant-opts { display: flex; gap: 0.4rem; flex-wrap: wrap; }

.variant-opt {
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  padding: 0.5rem 1rem;
  border: 1px solid var(--border-2);
  background: transparent;
  color: var(--cream-dim);
  border-radius: var(--r);
  cursor: pointer;
  transition: border-color var(--dur-2), color var(--dur-2), background var(--dur-2);
}

.variant-opt:hover,
.variant-opt.active {
  border-color: color-mix(in srgb, var(--cream) 60%, transparent);
  color: var(--cream);
  background: color-mix(in srgb, var(--cream) 5%, transparent);
}

.product-info__price {
  font-family: var(--font-d);
  font-size: 2.25rem;
  font-weight: 700;
  color: var(--cream);
  margin-bottom: 1.5rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.product-info__price-unit {
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  color: var(--muted);
  font-weight: 400;
}

.product-info__ship {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1rem;
  font-family: var(--font-m);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.ship-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #3a8f5c;
  flex-shrink: 0;
}

/* Fiyat tazelik damgası — ürün sayfası (build-pages .pd-fresh) */
.pd-fresh {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.9rem 0 0;
  font-family: var(--font-m);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.pd-fresh .ship-dot { background: var(--muted); opacity: 0.8; }
/* Okuyamadığımız gece için: dolu nokta = doğrulandı, boş halka = veri yok (katalog
   kartıyla aynı gramer, yeni renk yok). */
.pd-fresh--stale .ship-dot { background: transparent; box-shadow: inset 0 0 0 1px var(--muted); opacity: 1; }

/* Fiyat tazelik damgası — katalog kartı (kaynak: sağlık defteri sonOk, priceUpdated DEĞİL) */
.agg-card__fresh {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-family: var(--font-m);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.agg-card__fresh .ship-dot { width: 5px; height: 5px; background: var(--muted); opacity: 0.7; }
/* Marka gece taramasında düştüyse rozet bunu SÖYLER; sessizce eski tarihi göstermek
   yanıltıcı olurdu. Yeni renk YOK: bu bir alarm değil, bilmediğimizin beyanı — ve
   "stokta yok" rozeti de renkle değil metinle konuşuyor (aynı ölçülü register).
   Ayrım noktanın İÇİNİN BOŞALMASI: doldurulmuş nokta = doğrulandı, boş halka = veri yok. */
.agg-card__fresh.is-stale .ship-dot {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--muted);
  opacity: 1;
}

/* "Bu bilgide hata var" tek-tuş bildirim — ürün sayfası (item 3, S-TRUST) */
.pd-report { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border); }
.pd-report__toggle {
  font-family: var(--font-m); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
  transition: color 0.2s ease;
}
.pd-report__toggle:hover { color: var(--cream-dim); }
.pd-report__panel { margin-top: 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
.pd-report__label { font-size: 0.75rem; color: var(--cream-dim); margin: 0; }
.pd-report__reasons { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.pd-report__reason {
  font-family: var(--font-m); font-size: 0.62rem; letter-spacing: 0.04em;
  color: var(--cream-dim); background: var(--surface, rgba(255,255,255,0.03));
  border: 1px solid var(--border); border-radius: 4px;
  padding: 0.4rem 0.7rem; cursor: pointer; transition: all 0.18s ease;
}
.pd-report__reason:hover { border-color: var(--muted); color: var(--cream); }
.pd-report__reason.is-on { border-color: var(--pop); color: var(--pop); background: rgba(255,255,255,0.04); }
.pd-report__note {
  font-family: var(--font-b); font-size: 0.8rem; color: var(--cream);
  background: rgba(255,255,255,0.03); border: 1px solid var(--border);
  border-radius: 4px; padding: 0.6rem 0.7rem; resize: vertical; min-height: 2.4rem;
}
.pd-report__note:focus { outline: none; border-color: var(--muted); }
.pd-report__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.pd-report__send {
  align-self: flex-start;
  font-family: var(--font-m); font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--bg); background: var(--cream);
  border: 0; border-radius: 4px; padding: 0.5rem 1.1rem; cursor: pointer;
  transition: opacity 0.2s ease;
}
.pd-report__send:disabled { opacity: 0.4; cursor: not-allowed; }
.pd-report__status:empty { display: none; }
.pd-report__status { font-size: 0.72rem; color: var(--muted); margin: 0; }

/* ---- Agregatör / Karşılaştırma Platformu ---------- */

/* Arama kutusu */
.agg-search {
  display: flex; align-items: center; gap: 0.6rem;
  max-width: 640px; margin: 1.75rem auto 0;
  background: var(--bg-card); border: 1px solid var(--border-2);
  border-radius: 999px; padding: 0.85rem 1.25rem;
  color: var(--cream-dim);
}
.agg-search:focus-within { border-color: var(--cream-dim); }
.agg-search input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--cream); font-family: var(--font-b); font-size: 0.9rem;
}
.agg-search input::placeholder { color: var(--muted); }

/* Sıralama — flag'lerle aynı kutu, içi yerli <select> (mobilde OS seçicisi açılır,
   elde yazılmış bir liste taklidinden her zaman iyidir). */
.agg-sort {
  display: inline-flex; align-items: center; min-height: 34px;
  background: var(--bg-3); border: 1px solid var(--border-3);
  border-radius: var(--r); padding: 0.26rem 0.6rem;
}
.agg-sort__k {
  font-family: var(--font-m); font-size: 0.76rem;
  color: var(--cream-dim); flex: none;
}
.agg-sort select {
  font-family: var(--font-m); font-size: 0.76rem; letter-spacing: 0.01em;
  color: var(--cream); background: none;
  border: 0; outline-offset: 3px;
  padding: 0 0 0 0.15rem; cursor: pointer; max-width: 12.5rem;
}
.agg-sort:focus-within { border-color: var(--pop-line-2); }

/* sayaç → index hero'nun → { } JSON telemetri readout register'ı (canlı) */
.agg-count {
  font-family: var(--font-m); font-size: 0.8rem; letter-spacing: 0.01em;
  text-transform: none; color: var(--cream-dim);
  padding: 0 2.5rem; margin-top: 1.5rem;
}
.agg-disclaimer {
  font-size: 0.72rem; color: var(--muted); line-height: 1.6;
  padding: 0.4rem 2.5rem 0;
}
.agg-disclaimer strong { color: var(--pop); }

/* Görünürlük / tarafsızlık güven satırı — item 2 (şimdilik yalnız Organik aktif) */
.agg-trust {
  display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap;
  font-size: 0.72rem; color: var(--muted); line-height: 1.6;
  padding: 0.5rem 2.5rem 0;
}
.agg-trust__badge {
  font-family: var(--font-m); font-size: 0.56rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 500;
  color: #3a8f5c; background: rgba(58,143,92,0.12);
  border: 1px solid rgba(58,143,92,0.3);
  padding: 0.18rem 0.5rem; border-radius: 3px;
}
.agg-trust strong { color: var(--cream-dim); font-weight: 600; }
.agg-trust a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.agg-trust a:hover { color: var(--cream); }

/* Aktif tat ailesi → o tatın statik /liste/ sayfasına derin link */
.agg-listlink {
  display: inline-flex; align-items: baseline; gap: 0.4rem;
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--pop);
  margin: 0.6rem 2.5rem 0; padding-bottom: 1px;
  border-bottom: 1px solid color-mix(in srgb, var(--pop) 35%, transparent);
  transition: border-color var(--dur-2), color var(--dur-2);
}
.agg-listlink:hover { color: var(--cream); border-bottom-color: var(--cream); }
.agg-listlink[hidden] { display: none; }
.agg-listlink span { transition: transform var(--dur-2); }
.agg-listlink:hover span { transform: translateX(2px); }

/* Izgara + kart */
/* Rakam-yoğun alanlar — fiyatlar dikey hizalansın */
.agg-grid, .cmp-table { font-variant-numeric: tabular-nums; }
.agg-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1rem; padding: 1.5rem 2.5rem 4rem;
}
.agg-card {
  display: flex; flex-direction: column;
  /* ⚠️ Izgara öğesinin otomatik asgari boyu min-content'tir: karttaki `nowrap`
     tadım notu kartı sütundan GENİŞ yapıyordu. 390'da kart 363px (sütun 342),
     360'ta 27px ekran dışına taşıyor ve html/body `overflow-x:clip` olduğu için
     sessizce kırpılıyordu — yani uzun notlu kartların sağ kenarı yoktu. */
  min-width: 0;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 6px; padding: 1.4rem 1.4rem 1.2rem;
  transition: border-color var(--dur-4) var(--ease), transform var(--dur-4) var(--ease), box-shadow var(--dur-4) var(--ease);
  transform-style: preserve-3d;
  position: relative;
}
.agg-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.12);
  border-radius: 6px;
  transform: translateZ(-16px) scaleX(1.02) scaleY(1.02);
  opacity: 0;
  transition: opacity var(--dur-4) var(--ease);
  pointer-events: none;
}
.agg-card:hover::after { opacity: 1; }
.agg-card:hover { border-color: var(--border-2); transform: translateY(-6px); }
.agg-card__brand { transform: translateZ(8px); }
.agg-card__price { transform: translateZ(12px); }
.agg-card.is-featured {
  border-color: color-mix(in srgb, var(--pop) 50%, transparent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--pop) 8%, transparent), var(--bg-card) 60%);
}
.agg-card__head { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-bottom: 0.6rem; }
.agg-card__brand {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--cream-dim);
}
.agg-card__badge {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--bg);
  background: var(--pop); border-radius: 999px; padding: 0.2rem 0.5rem; white-space: nowrap;
}
.agg-card__name {
  font-family: var(--font-d); font-size: 1.35rem; font-weight: 600;
  color: var(--cream); line-height: 1.1; margin-bottom: 0.3rem;
}
/* Çok sütunlu ızgarada iki satırlık yer AYRILIR: aksi halde tek satırlık adı olan
   kartın kavurma rayı, iki satırlık komşusununkinden 24px yukarıda duruyor ve satır
   bir hizaya oturmuyordu. Kartlar zaten eşit yükseklikte (stretch) — ayrılan yer
   bedava. Tek sütunlu mobilde hizalanacak komşu yok, orada uygulanmaz. */
@media (min-width: 641px) {
  /* 29 Ağu: yer ayırmak yetmiyordu, KIRPMA da gerekti. Ölçüldü (281px blok eninde):
     612 ad 1 satır · 412 ad 2 satır · 22 ad ÜÇ satır — o 22'si ayrılan yeri taşırıp
     altındaki her şeyi aşağı itiyordu. Karakter eşiği DENENDİ ve elendi: tek satırda
     kalan en uzun ad 30 karakter, iki satıra taşan en kısa ad 25 ("Guatemala ·
     Huehuetenango" — sarmayı uzunluk değil bölünmez kelime zorluyor); 25-30 arası
     bandda karakter sayısı karar veremiyor. line-clamp neyin GERÇEKTEN sardığını
     ölçer. Tam ad <a title> içinde kalır, kesilmez. */
  .agg-card__name {
    min-height: 2.97rem;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
}
.agg-card__name a { color: inherit; text-decoration: none; transition: color var(--dur-2); }
.agg-card__name a:hover { color: var(--pop); }
a.agg-card__brand { text-decoration: none; transition: color var(--dur-2); }
a.agg-card__brand:hover { color: var(--pop); }

/* Keşif hub'ı — "şerit" (kahveler.html · build-pages.js doldurur, 3 Ağu 2026)
   77 kavurmacı üç kayan bantta. Gramer ana sayfadaki borsa bandından; burada
   sayı değil AD taşınır. Gerekçe + kararın tarihi build-pages.js renderHub()'da. */
.browse-hub {
  max-width: 1200px; margin: 0 auto; padding: 3.5rem 1.5rem;
  border-top: 1px solid var(--border);
}
.browse-hub__title {
  font-family: var(--font-m); font-size: 0.66rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--pop); margin-bottom: 0.6rem;
}
.browse-hub__title--2 { margin-top: 3.2rem; }
.browse-hub__legend {
  font-size: 0.82rem; line-height: 1.55; color: var(--muted-2);
  max-width: 60ch; margin-bottom: 1.6rem;
}
.browse-hub__tapes { margin-bottom: 0.5rem; }

/* Bant: kenarları maskeyle söner, içerik iki kez basılıdır (kesintisiz döngü). */
.bh-tape {
  overflow: hidden; padding: 0.62rem 0; border-top: 1px solid var(--border);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.bh-tape:last-child { border-bottom: 1px solid var(--border); }
.bh-tape__t {
  display: inline-flex; align-items: baseline; gap: 1.05rem;
  white-space: nowrap; will-change: transform;
}
.bh-tape__dup { display: inline-flex; align-items: baseline; gap: 1.05rem; }
.bh-tape__t a {
  font-family: var(--font-d); font-size: 1.12rem; font-weight: 600;
  color: var(--cream-dim); text-decoration: none; transition: color var(--dur-2);
}
.bh-tape__t a:hover, .bh-tape__t a:focus-visible { color: var(--pop); }
.bh-tape__t i { font-style: normal; color: var(--border-3); }
.bh-tape__t--0 { animation: bhTape 90s linear infinite; }
.bh-tape__t--1 { animation: bhTape 112s linear infinite reverse; }
.bh-tape__t--2 { animation: bhTape 78s linear infinite; }
/* durdurma: imleç VE klavye odağı — Tab ile gezen kullanıcı hareketli bant kovalamaz */
.bh-tape:hover .bh-tape__t, .bh-tape:focus-within .bh-tape__t { animation-play-state: paused; }
@keyframes bhTape { to { transform: translateX(-50%); } }
/* İç sayfa: reduce TAM saygılı (ana sayfa kimlik-hareketi istisnası burada geçmez).
   Hareket durur, bant elle kaydırılabilir şeride döner — içerik kaybolmaz. */
@media (prefers-reduced-motion: reduce) {
  .bh-tape { overflow-x: auto; }
  .bh-tape__t { animation: none; }
  .bh-tape__dup { display: none; }
}

/* liste bağlantıları: ikinci yığın değil, çip şeridi */
.browse-hub__cips { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.bh__cip {
  font-family: var(--font-m); font-size: 0.68rem; color: var(--cream-dim); text-decoration: none;
  border: 1px solid var(--border-2); padding: 0.34rem 0.6rem;
  transition: border-color var(--dur-2), color var(--dur-2);
}
.bh__cip:hover { color: var(--cream); border-color: var(--pop-line-2); }
@media (max-width: 640px) {
  .browse-hub { padding: 2.5rem 1.25rem; }
  .bh-tape__t a { font-size: 1rem; }
}
.agg-card__meta {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 0.75rem;
}
/* Nitelik satırı: kavurma solda, işlem çipi sağda — tek satır, iki blok değil. */
.agg-card__attrs {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.6rem; margin-bottom: 0.75rem; min-height: 26px;
}
.agg-card__attrs > .agg-x--roast,
.agg-card__attrs > .roast-scale { flex: 1; min-width: 0; }
.agg-card__attrs .roast-scale { margin-bottom: 0; }
/* Kimlik satırı (29 Ağu): çip + demleme yöntemleri. İki öğe, sarabilir.
   Kartın "bu ne" bölgesi; "nasıl işlendi" ayrı satırda (.agg-card__attrs). */
.agg-card__ident {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 0.75rem;
  /* 29 Ağu: sarma KAPALI + sabit yükseklik. Ölçüldü: satır kimi kartta 27px kimi
     kartta 53px'ti (ikinci satıra sarıyordu) ve altındaki her şey kayıyordu. Çip
     düşen kartlarda da yer korunur — boş, ama yerini tutar. */
  flex-wrap: nowrap; min-height: 26px; min-width: 0;
}
.agg-card__ident > * { min-width: 0; }
.agg-card__ident .agg-card__meta {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agg-card__ident .agg-card__meta { margin-bottom: 0; }

.agg-card__chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.8rem; }

/* Karttaki nitelik köprüleri (28 Tem) — menşei · yöntem · kavurma · işlem · tadım notası.
   SESSİZ dururlar, kapı olduklarını hover'da söylerler: kart zaten üç gerçek bağlantı
   taşıyor (marka · ürün adı · satıcıya git) ve altı niteliği daha renklendirmek kartı
   bağlantı çorbasına çevirirdi. Çipin kendi rengi korunur, yalnız kenarı canlanır. */
.agg-x {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-2), color var(--dur-2);
}
.agg-x:hover { color: var(--cream); border-bottom-color: color-mix(in srgb, var(--pop) 55%, transparent); }
.agg-x--roast { display: block; border-bottom: 0; }
.agg-x--roast:hover .roast-scale__label { color: var(--pop); }
.agg-x--chip { display: inline-block; border-bottom: 0; }
.agg-x--chip:hover .process-chip { border-color: currentColor; }
.agg-card__notes .agg-x { color: inherit; }
.agg-card__notes {
  font-size: 0.82rem; color: var(--cream-dim); line-height: 1.55; margin-bottom: 0.9rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agg-card__foot {
  margin-top: auto; margin-bottom: 0.9rem;
  /* 29 Ağu: ayak DİBE yapışık ama fiyat ayağın TEPESİNDE — ayak uzayınca fiyat yukarı
     iter. line2 sabitlendikten sonra kalan tek değişken değer rayıydı (kıyasa girmeyen
     üründe hiç basılmıyor, ~17px). Sabit yükseklik rayın yerini yokken de tutar; artan
     boşluk alta düşer, fiyat satırı yerinde kalır. Ray gramerinin kendisi (boş ray =
     "ölçek var, değeri yok") 5 Ağu'da kilitlendi, burada yalnız yeri korunuyor. */
  /* ⚠️ Burada min-height YOK, bilerek. Denendi: ölçülen en uzun ayağı (79px) sabit
     yazmak hizayı düzeltiyordu ama sayı fiyat puntosu ya da hüküm satırı değişince
     SESSİZCE bayatlardı (karar #13'ün kalıbı). Ayağın yüksekliğini sabitleyen şey
     artık içeriğin kendisi: değer rayı kıyasa girmeyen üründe de YER TUTAR
     (.vrail--yok), line2 tek satıra kilitli, fiyat satırı zaten sabit. */
}
/* Ham fiyat solda, kıyas parası (₺/100g) sağ rayda: kartlar yan yana gelince
   karşılaştırılan sayı aynı hizada durur. */
.agg-card__price {
  display: flex; align-items: baseline; gap: 0.35rem;
  font-family: var(--font-d); font-size: 1.1rem; color: var(--cream);
}
.agg-card__price strong { font-weight: 700; }
.agg-card__price span { font-size: 0.7rem; color: var(--cream-dim); }
.agg-card__unit {
  flex: none; margin-left: auto;      /* gramaj fiyata yapışır, birim sağ raya gider */
  font-family: var(--font-m); font-size: 0.65rem;
  letter-spacing: 0.06em; color: var(--muted);
}
/* DEĞER RAYI (5 Ağu) — ₺/100g'nin piyasa içindeki yeri KONUMLA.
   Ray = medyan ×0,5 … ×2 (log2), datum tam ortada. Datum her kartta aynı x'te durduğu
   için ızgarada ortak bir dikey referans doğar: iki kartın hangisinin daha ucuz olduğu
   iki yüzdeyi okumadan görünür. Geometri core.js → kfValuePos.
   Yükseklik bütçesi 9px: kart 5 Ağu'da 945px'ten indirilmişti, geri şişirilmiyor. */
.vrail {
  display: block;                    /* bp-card'da <span> olarak da basılıyor (flex çocuğu) */
  position: relative; height: 9px; margin-top: 0.5rem;
  /* taban: tam genişlik hairline, dikey ortada */
  background: linear-gradient(var(--border-2), var(--border-2)) 0 50%/100% 1px no-repeat;
}
/* Datum = piyasa medyanı. Rayın kendisinden biraz parlak, ama işaretten sönük:
   referans okunmalı, dikkati işaret almalı. */
/* Kıyasa girmeyen ürün: ray çizilmez ama yeri korunur. görünürlük kapalı, akışta
   duruyor — display:none olsaydı ayak kısalır ve fiyat satırı kayardı. */
.vrail--yok { visibility: hidden; }

.vrail__datum {
  position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;
  margin-left: -0.5px;               /* 1px çizgiyi ortala: left:50% SOL KENARI ortalar */
  background: var(--muted);
}
/* Bu kahvenin yeri. Kare (ray yuvarlak değil) + minimal radius sistemine uyar. */
.vrail__tick {
  position: absolute; top: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px;
  background: var(--save); border-radius: 1px;
  box-shadow: 0 0 7px -1px var(--save);
}
/* Renk YARDIMCI kanal, tek kanal değil: konum tek başına anlamı taşır (Few 2005 —
   nitel bant ayrı hue'larla değil konum/tonla kodlanır, gerekçe renk körlüğü).
   Kartın mevcut dili korunuyor: medyan altı --save, üstü/eşiti --muted. */
.vrail--up .vrail__tick,
.vrail--flat .vrail__tick { background: var(--muted); box-shadow: none; }

/* Hüküm + kontrol tarihi tek satır (eskiden iki ayrı blok, 40px fazladan) */
.agg-card__line2 {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.35rem 0.75rem; margin-top: 0.45rem;
  /* 29 Ağu — KARTIN HİZASIZLIĞININ KAYNAĞI BURASIYDI. Ölçüldü: aynı satırdaki dört
     kartın ayak yüksekliği 57/57/73/95px, fiyat satırı 247/247/231/209'da duruyordu;
     farklar birebir. Ayak margin-top:auto ile dibe yapışık ama fiyat ayağın TEPESİNDE,
     yani ayak uzayınca fiyat yukarı itiliyor.
     ⚠️ İLK ÇÖZÜM YANLIŞTI: sarmayı kapatıp kırpmak denendi ve 142 kartın 22'sinde
     (%15) metin kelime ortasından kesildi — kesilenlerin arasında "medyanın %24
     altında" da vardı, yani ürünün kendisi. Sarmayı kırpmayla takas etmek, hizayı
     iddianın okunabilirliğiyle satın almaktı.
     Doğrusu: satır İKİ SATIRLIK yer tutar ve sarabilir. İkinci satır çoğu kartta boş
     kalır ama yerini korur; hiçbir şey kesilmez, ayak sabit kalır. Kupa fişi grameri:
     boş, gizlenmez. Bedeli ölçüldü: kart +13px. */
  min-height: 2.3rem; align-content: flex-start;
}
.agg-card__line2 > * { min-width: 0; }

/* Değer hükmü — ₺/100g medyana göre; index borsa readout'unun kart-içi izi.
   ▼ medyan altı = değer (--save mint) · ▲ üstü/flat = muted. Tarafsızlık moat'ı görselde. */
.agg-card__verdict {
  display: inline-flex; align-items: center; gap: 0.32em;
  font-family: var(--font-m); font-size: 0.66rem; letter-spacing: 0.01em;
  color: var(--save);
}
/* canlı telemetri: ok yanıp söner (index tape bx2-blink register'ı) — hafif faz
   kaydırma ile organik, senkron strobe değil. reduced-motion'da durur (iç sayfa). */
.agg-card__verdict .arw {
  font-size: 0.82em;
  animation: agg-blink 1.7s ease-in-out infinite;
}
/* Faz kaydırma kuralları KALKTI (5 Ağu): katalog ızgarasındaki ok yerini değer rayına
   bıraktı, ok artık yalnız karşılaştırma tablosunda ve ürün sayfasında — ikisinde de
   yan yana çok sayıda ok yok, dolayısıyla senkron strobe diye bir sorun da yok.
   Gerekçe sıklık kapısı: ızgarada 40 yanıp sönen ok, taranması gereken kanalı (konum)
   bastırıyordu. */
@keyframes agg-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
.agg-card__verdict--up,
.agg-card__verdict--flat { color: var(--muted); }
/* Kapı dışı ürün (Türk kahvesi · kapsül · harman · notsuz): ray YOK, çünkü medyanın
   kümesinde değiller. Sessiz boşluk bırakmıyoruz — sebebi yazılı ve tıklanabilir. */
.agg-card__verdict--na { color: var(--muted-2); }
.agg-card__verdict--na a { color: inherit; border-bottom: 1px dotted var(--border-2); }
.agg-card__verdict--na a:hover { color: var(--cream-dim); border-bottom-color: currentColor; }

@media (prefers-reduced-motion: reduce) {
  .agg-card__verdict .arw { animation: none; }
}
.agg-card__actions { display: flex; gap: 0.5rem; }
.agg-cmp {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.08em;
  color: var(--cream-dim); background: var(--bg-2);
  border: 1px solid var(--border-2); border-radius: 4px;
  padding: 0.55rem 0.7rem; cursor: pointer; white-space: nowrap;
  transition: all var(--dur-3) var(--ease);
}
.agg-cmp:hover { color: var(--cream); }
.agg-cmp.is-on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
.agg-go {
  flex: 1; text-align: center; text-decoration: none;
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.08em;
  color: var(--cream); background: var(--bg-2);
  border: 1px solid var(--border-2); border-radius: 4px;
  padding: 0.55rem 0.7rem; transition: all var(--dur-3) var(--ease);
}
.agg-go:hover { border-color: var(--cream-dim); }

/* Stok durumu — günlük döngü stok bitince işaretler (SİLME yok, memory stock-signal-false-label).
   Kart sönükleşir + baş köşede mono rozet + satın-al pasif. Yeşil DEĞİL (yeşil = canlı/pozitif). */
.agg-card--out { opacity: 0.62; }
.agg-card--out:hover { opacity: 0.8; }
.agg-card__stock {
  font-family: var(--font-m); font-size: 0.56rem; letter-spacing: 0.08em; text-transform: lowercase;
  color: var(--muted); border: 1px solid var(--border-2); border-radius: 3px;
  padding: 0.15em 0.45em; white-space: nowrap; flex: none;
}
.agg-go--out {
  flex: 1; text-align: center; cursor: not-allowed;
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.08em; text-transform: lowercase;
  color: var(--muted-2); background: transparent;
  border: 1px dashed var(--border-2); border-radius: 4px; padding: 0.55rem 0.7rem;
}
.agg-empty { grid-column: 1 / -1; text-align: center; color: var(--cream-dim); padding: 3rem 0; }

/* Tat filtresi ayracı: tadım notu bilinmeyen ürünler (Faz 1.2) — sessizce elemek
   yerine dürüst bir sınır çizgisi. Terminal register'ı: `//` yorum satırı. */
.agg-unknown {
  grid-column: 1 / -1; margin: 1.2rem 0 0.2rem; padding-top: 1.2rem;
  border-top: 1px dashed var(--border-2);
  font-family: var(--font-m); font-size: 0.68rem; line-height: 1.5;
  letter-spacing: 0.02em; color: var(--cream-dim);
}

/* "Daha fazla göster" — grid'in altında ortalı, artımlı render */
.agg-more {
  display: block; margin: -2.5rem auto 3.5rem;
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--cream);
  background: var(--bg-2); border: 1px solid var(--border-2); border-radius: 4px;
  padding: 0.85rem 2rem; cursor: pointer;
  transition: border-color var(--dur-3) var(--ease), color var(--dur-3) var(--ease);
}
.agg-more:hover { border-color: var(--cream-dim); color: var(--pop); }
.agg-more[hidden] { display: none; }

/* Karşılaştırma sayfası */
.cmp-wrap { padding: 1rem 2.5rem 4rem; }
.cmp-empty { text-align: center; color: var(--cream-dim); padding: 3.5rem 0 4rem; }
.cmp-empty__lead {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted-2); margin-bottom: 1.5rem;
}
/* preset kartı = index "❯ günün lideri" kartının karsilastir analoğu → aynı yeşil
   terminal register (amber --act dekoratif kullanımı emekli, color-consistency). */
.cmp-preset {
  max-width: 30rem; margin: 0 auto; text-align: left;
  background: var(--bg-card); border: 1px solid var(--border-2);
  border-left: 2px solid var(--pop); border-radius: 3px;
  padding: 1.5rem 1.6rem 1.7rem;
}
.cmp-preset__label {
  display: inline-flex; align-items: center; gap: 0.4em;
  font-family: var(--font-m); font-size: 0.65rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--pop);
  margin-bottom: 0.6rem;
}
.cmp-preset__label::before { content: "\276F"; opacity: 0.7; }   /* ❯ index leader register'ı */
.cmp-preset__title {
  font-family: var(--font-d); font-size: 1.5rem; line-height: 1.15;
  color: var(--cream); font-weight: 600; margin-bottom: 0.5rem;
}
.cmp-preset__title span { white-space: nowrap; }
.cmp-preset__sub { font-family: var(--font-b); font-size: 0.82rem; color: var(--cream-dim); margin-bottom: 1.1rem; }
.cmp-preset__list { list-style: none; margin: 0 0 1.4rem; padding: 0; border-top: 1px solid var(--border); }
.cmp-preset__list li {
  font-family: var(--font-b); font-size: 0.85rem; color: var(--cream);
  padding: 0.55rem 0; border-bottom: 1px solid var(--border);
}
.cmp-preset__brand {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin-right: 0.45rem;
}
.cmp-preset__load { width: 100%; justify-content: center; }
.cmp-empty__browse {
  display: inline-block; margin-top: 1.4rem; font-family: var(--font-b);
  font-size: 0.8rem; color: var(--muted); border-bottom: 1px solid var(--border-2);
  transition: color var(--dur-3) var(--ease);
}
.cmp-empty__browse:hover { color: var(--cream-dim); }
.cmp-scroll { overflow-x: auto; }
.cmp-table { border-collapse: collapse; width: 100%; min-width: 520px; }
.cmp-table th, .cmp-table td {
  border: 1px solid var(--border); padding: 1rem 1.1rem;
  text-align: left; vertical-align: top; font-size: 0.85rem; color: var(--cream-dim);
}
.cmp-rowhead {
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
  background: var(--bg-2); width: 110px;
  /* 390px'te tablo yatay kayarken satır etiketi sabit kalsın (22 Ağu). */
  position: sticky; left: 0; z-index: 2;
}
.cmp-col { position: relative; background: var(--bg-card); min-width: 150px; }
.cmp-col.is-featured { background: linear-gradient(180deg, color-mix(in srgb, var(--pop) 8%, transparent), var(--bg-card)); }
.cmp-col__brand { display: block; font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cream-dim); margin-bottom: 0.3rem; }
.cmp-col__brand em { color: var(--pop); font-style: normal; }
.cmp-col__name { display: block; font-family: var(--font-d); font-size: 1.1rem; font-weight: 600; color: var(--cream); line-height: 1.1; }
.cmp-remove {
  position: absolute; top: 0.5rem; right: 0.5rem;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--bg-2); border: 1px solid var(--border-2);
  color: var(--cream-dim); cursor: pointer; line-height: 1;
}
.cmp-remove:hover { color: var(--cream); border-color: var(--cream-dim); }
.cmp-table td strong { color: var(--cream); }
.cmp-best { color: var(--save); font-weight: 700; }
/* ₺/100g hücresinde değer verdict → fiyatın altına (kahveler kart diliyle aynı) */
.cmp-table td .agg-card__verdict { display: flex; margin-top: 0.3rem; }
.cmp-actions { display: flex; gap: 0.75rem; margin-top: 1.5rem; flex-wrap: wrap; }

/* Bağımsız katalog sayfası — nav boşluğunu header (.inner-hero) yönetir */
.kahveler-page {
  min-height: 100vh;
  animation: none;
}

/* Katalog editorial header — inner-hero türevi (.inner-hero layout.css'te) */
.inner-hero--catalog { padding-bottom: 2.25rem; }
.inner-hero--catalog h1 {
  font-size: clamp(2.4rem, 5.5vw, 3.6rem);
  font-weight: 700;
}
.inner-hero--catalog h1 em { font-style: italic; color: var(--pop); }
.inner-hero--catalog .inner-hero__body { margin-top: 1rem; }

/* ---- kafdeks terminal dili — S2 kimlik bütünlüğü (iç sayfa hero'yu ana
   sayfanın kafdeks/D3 diline çeker: mono log eyebrow · JetBrains 800 lowercase
   başlık, dik yeşil em · // mono sub). CSS-only → catalog.js başlık swap'ı bozulmaz. */
.inner-hero--kb .inner-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-m);
  text-transform: lowercase;
  letter-spacing: 0.02em;
  color: var(--cream-dim);
}
.inner-hero--kb .inner-hero__eyebrow::before {
  content: "\276F";            /* ❯ — terminal istem glifi (ana sayfa idiomu) */
  color: var(--pop);
  font-size: 0.9em;
}
.inner-hero--kb h1 {
  font-family: var(--font-d);   /* Archivo 800 — hero ile tutarlı (eski JetBrains Mono emekli) */
  font-weight: 800;
  font-size: clamp(2rem, 4.6vw, 3.2rem);
  letter-spacing: -0.03em;
  line-height: 1.08;
  text-transform: lowercase;
}
.inner-hero--kb h1 em { font-style: normal; color: var(--pop); }   /* italik → dik yeşil */
.inner-hero--kb .inner-hero__body {
  font-family: var(--font-m);
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--cream-dim);
}
.inner-hero--kb .inner-hero__body::before { content: "// "; color: var(--muted-2); }
.inner-hero--kb .kahveler-sec__q { text-transform: lowercase; letter-spacing: 0.04em; }

/* Veri sayfası terminal register — .page-header primitive (karsilastir vb). inner-hero--kb aynası. */
.page-header--kb .page-header__eyebrow {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-m); text-transform: lowercase; letter-spacing: 0.02em; color: var(--cream-dim);
}
.page-header--kb .page-header__eyebrow::before { content: "\276F"; color: var(--pop); font-size: 0.9em; }
.page-header--kb h1 {
  font-family: var(--font-d); font-weight: 800;
  font-size: clamp(2rem, 4.6vw, 3.2rem); letter-spacing: -0.03em; line-height: 1.08; text-transform: lowercase;
}
.page-header--kb h1 em { font-style: normal; color: var(--pop); }
.page-header--kb .page-header__sub {
  font-family: var(--font-m); font-size: 0.9rem; line-height: 1.7; color: var(--cream-dim);
}
.page-header--kb .page-header__sub::before { content: "// "; color: var(--muted-2); }

/* Çipler flex + gap ile aralanır, kardeş margin'iyle DEĞİL: `.agg-axis + .agg-axis
   { margin-left }` satır içinde doğru görünüyordu ama SARINCA girinti oluyordu —
   375px'te ikinci çip 24px içeriden başlıyor, hizasız bir sütun gibi okunuyordu
   (föy: .shots/durak2/kat-01-varis.png). Aradaki fark yalnız dar ekranda görülür;
   masaüstünde çipler hiç sarmıyor, o yüzden 29 Tem'den beri fark edilmemişti. */
.kahveler-sec__q {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.7rem;
  font-family: var(--font-m); font-size: 0.65rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--cream-dim); margin-top: 0.85rem;
}
.kahveler-sec__q:empty { display: none; }

/* Aktif eksen çipi — derin linkle gelen filtrenin görünür kapatma yolu (`--origin=… ×`).
   Menşei/işlem filtre çubuğunda düğme taşımıyor; bu çip olmasa tek çıkış URL'i elle
   düzeltmek olurdu. */
.agg-axis {
  display: inline-flex; align-items: center; gap: 0.45rem;
  color: var(--pop); text-decoration: none; text-transform: none; letter-spacing: 0.08em;
  border: 1px solid color-mix(in srgb, var(--pop) 30%, transparent);
  padding: 0.22rem 0.55rem;
  transition: border-color var(--dur-2), color var(--dur-2);
}
.agg-axis:hover { border-color: var(--pop); color: var(--cream); }
/* Aralık kabın `gap`inden gelir (yukarı bak) — kardeş margin'i sarınca girinti yapar. */
/* "neden?" — çip değil dipnot: kapının gerekçesine köprü (nasil-hesapliyoruz#kiyas) */
.agg-axis--why { color: var(--muted); border-color: transparent; border-bottom: 1px dotted var(--border-3); padding: 0.22rem 0.1rem; }
.agg-axis--why:hover { border-color: transparent; border-bottom-color: var(--pop); }

/* ---- Catalog Responsive --------------------------- */
@media (max-width: 1100px) {
  .collection-grid   { grid-template-columns: repeat(2, 1fr); }
  .product-layout    { grid-template-columns: 1fr; }
  .product-gallery   { position: relative; height: 60vw; min-height: 320px; }
  .product-info      { max-height: none; }
}

@media (max-width: 768px) {
  .collection-grid { padding: 2rem 1.5rem; }
}

@media (max-width: 640px) {
  /* Ürün sayfası mobil kenar hizası: masaüstünün 3.5rem'i 390px ekranda içeriğe
     278px bırakıyordu. 1.5rem = katalog/karşılaştırma/header ile aynı token. */
  .product-info { padding: 2.5rem 1.5rem 3rem; }
  /* Breadcrumb kelime ortasından sarıyordu ("ANA / SAYFA"); tek satır kalır, taşarsa
     kendi içinde kayar — sayfa yatay kaymaz. */
  .product-info__crumb {
    flex-wrap: nowrap;
    white-space: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-bottom: 1.5rem;
  }
  .product-info__crumb::-webkit-scrollbar { display: none; }

  .agg-grid { padding: 1.5rem 1.5rem 4rem; grid-template-columns: 1fr; }
  .agg-count, .agg-disclaimer, .agg-trust { padding-left: 1.5rem; padding-right: 1.5rem; }
  .cmp-wrap { padding: 1rem 1.5rem 4rem; }

  /* Katalog header — kartlarla aynı kenar hizası, taşma yok */
  .inner-hero--catalog {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
    padding-bottom: 1.75rem;
  }
  .inner-hero--catalog .inner-hero__body { font-size: 0.95rem; }

  /* Mobil komut satırı: açılan panel yalnız seçilen eksenin listesini indirir.
     Eskiden bütün eksenler açıktı ve çubuk 713px = ekranın %85'i tutuyordu. */
  /* Dolgu 1rem → 0.7rem: çubuk artık yapışık (aşağı bak), yani bu yükseklik ekranın
     kalıcı gideri. Bayraklar kendi 40px dokunma hedeflerini taşıdığı için dış dolgu
     nefes almak zorunda değil; 667px ekranda 147px yerine 133px kalıcı çerçeve. */
  .filter-bar { padding: 0.7rem 1.5rem; }
  .fb__pmt { display: none; }          /* dar ekranda satırın parasını flag'ler hak ediyor */
  .fb__cmd { gap: 0.4rem; }
  .fb__flag, .agg-sort { min-height: 40px; }
  .fb__flag { font-size: 0.74rem; padding: 0.26rem 0.5rem; gap: 0.4rem; }
  .fb__flag b { padding-left: 0.4rem; }
  .agg-sort { padding: 0.26rem 0.5rem; }

  /* ===== Mobil varış: ilk kahveyi ekrana getir (5 Ağu — Çağkan bildirdi:
     "butonlardan birine basıp girdiğimizde tüm ekranı kaplayan yazılar ve filtre
     istasyonu ile karşılaşıyoruz").
     ÖLÇÜLDÜ (375×667, huninin kendi bağlantısıyla): ilk kart 945px'te başlıyordu —
     1,4 ekran kaydırma. Emsal turu iki ölçülmüş bulgu verdi: kullanıcı bir listeyi
     İLK BİRKAÇ üründen yargılıyor (Baymard), ve filtre kontrolü kaydırma boyunca
     erişilebilir kalmalı — yukarıda kalıp kaybolan çubuk mobilin bilinen hatası.
     Sayfa ikisini de vermiyordu. Dört hamle, hepsi CSS, yalnız mobil: */

  /* (a) Yönlendirme metni düşer. Nerede olduğunu crumb + H1 + sayaç zaten üç kez
         söylüyor; dördüncüsünün bedeli 135px. Masaüstünde kalır (yeri var), metin
         sayfadan silinmez — SEO ve masaüstü okuru için markup yerinde. */
  .inner-hero--catalog .inner-hero__eyebrow,
  .inner-hero--catalog .inner-hero__body { display: none; }
  .inner-hero--catalog { padding-bottom: 1rem; }
  .agg-count { margin-top: 0.9rem; }

  /* (b) Bayraklar TEK SIRA, taşarsa kendi içinde kayar. Sarmak üç sıra ve 216px
         demekti; yatay kaydırma şeridi ana sayfa huninin tat şeridiyle aynı gramer. */
  .fb__cmd {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .fb__cmd::-webkit-scrollbar { display: none; }
  .fb__flag, .fb__reset, .agg-sort { flex: none; }

  /* (c) O satır nav'ın altına YAPIŞIR: filtre artık listeyi bırakmadan değişir.
         Panel açıkken de yapışık kalır ama bu kısa ömürlü — değer seçilince panel
         kendiliğinden kapanıyor (catalog.js `openPanel(null)`); kalıcı olsaydı
         sekiz pillik kavurma listesi ekranın dörtte birini sürekli yerdi. */
  .filter-bar {
    position: sticky;
    top: var(--nav-h);
    z-index: 40;
  }
  /* Açılan panel çubuğu BÜYÜTMEZ, üstüne iner. Yapışık bir kabın içinde akışta
     kalsaydı çubuk 87px'ten 250px'e çıkar ve altındaki her şey aşağı kayardı.
     Chrome bunu kaydırma çıpasıyla (scroll anchoring) gizliyor — ekran görüntüsünde
     kart yerinde duruyordu — ama SAFARI KAYDIRMA ÇIPASINI DESTEKLEMEZ: iPhone'da
     okunan kart 165px zıplardı. Ekran görüntüsü Chrome'daydı, yani bu kusuru föy
     GÖSTERMEZDİ; hüküm koddan verildi.
     `html.js` şartı bilerek: JS yokken paneller açık kalır (ilerlemeli geliştirme),
     mutlak konumda hepsi aynı noktada üst üste binerdi. */
  /* Panel açıkken sağ ray ÇEKİLİR (5 Ağu, İş 3). Ölçüldü: tat ekseninin dış halkası
     açıldığında `--narenciye 217` çipinin %30'u `.kv-rail`in altında kalıyor ve ray
     `pointer-events:auto` — yani hem sayı okunmuyor hem dokunuş rayı yakalayabiliyor.
     Kullanıcı filtre seçerken yüzen asistan düğmesi öncelik değil; durum kısa ömürlü,
     değer seçilince panel kendiliğinden kapanıyor ve ray geri geliyor.
     ⚠️ Tek noktalı `elementFromPoint` bu çakışmayı GÖRMEDİ (çipin sağ kenarında ray
     henüz başlamıyordu); hüküm alan kesişiminden çıktı. Bir sondaj çarpışma testi değildir.
     ⚠️ Kapı `:has()` DEĞİL kök sınıf: `:has()` sürümü ölçümde güvenilmez çıktı (seçici
     JS'te eşleşiyor, stil aynı anda uygulanmamış oluyordu). Sınıfı `openPanel()` yazar. */
  html.js.kf-panel-acik .kv-rail {
    /* ⚠️ `visibility` ŞART: yalnız opacity:0 odak sırasını temizlemez — ölçüldü, ray
       görünmezken içindeki iki düğme hâlâ odak alıyordu ve sekmeyle gezen kullanıcının
       odağı hiçliğe düşüyordu (WCAG 2.4.7).
       ⚠️ GEÇİŞ YOK. Solma denendi (`transition: opacity var(--dur-2), visibility 0s
       linear var(--dur-2)`) ve ölçümde 414px/430px'te opacity 1'de takılı kaldı; kural
       eşleşiyordu (CSS.getMatchedStylesForNode doğruladı) ama geçiş başlamıyordu.
       Sebebini kovalamak yerine değişkeni kaldırdım: ray anında çekilir. Emil'in sıklık
       kapısı da bunu ister — geçici bir engel kaçınması animasyon hak etmez. */
    display: none;
    visibility: hidden;
    pointer-events: none;
  }

  html.js .fb__panel.is-open {
    position: absolute; left: 0; right: 0; top: 100%;
    margin-top: 0; padding: 0.85rem 1.5rem 1rem;
    background: var(--bg-2);
    border-bottom: 1px solid var(--border);
    max-height: calc(100dvh - var(--nav-h) - 6rem);
    overflow-y: auto;
  }

  /* (d) Köken/güven notları listenin ALTINA iner. SİLİNMEZ — fiyatın nereden
         geldiğini ve sıralamanın satılmadığını söyleyen şeffaflık metni; yalnız
         sırası değişir, ilk kahve ile kullanıcının arasına girmesin diye.
     ⚠️ `order` TUZAĞI: atanmayan her çocuk 0 alır ve BAŞA geçer. "daha fazla göster"
        düğmesi JS ile grid'den sonra eklendiği için markup'ta yok, sınıf listesinde
        de yok — tek tek adlandırılsaydı sessizce sayfanın en üstüne çıkardı. O yüzden
        önce hepsine 5 verilir (grid'in hemen ardı), sonra bilinenler adlandırılır. */
  .kahveler-page { display: flex; flex-direction: column; }
  .kahveler-page > * { order: 5; }
  .kahveler-page > .inner-hero { order: 1; }
  .kahveler-page > .filter-bar { order: 2; }
  .kahveler-page > .agg-count { order: 3; }
  /* ⚠️ Görünüm anahtarı ADLANDIRILMAK ZORUNDA: adlandırılmazsa yukarıdaki `> *`
     kuralından 5 alır ve ızgaranın ARDINA düşer — ölçüldü, mobil kart görünümünde
     anahtar 9251px'te, yani 24 kartın altındaydı. Masaüstünde ızgaranın hemen
     üstünde duruyor; mobilde de orada durmalı, yoksa seçenek "var" ama bulunamaz.
     ⚠️ `.cat-cetvel` de burada: ızgaranın sınıfı görünüme göre değişiyor
     (`agg-grid` ⇄ `cat-cetvel`), yalnız `.agg-grid` adlandırılsaydı sıra
     görünüm değiştikçe kayardı — kayıyordu da. */
  .kahveler-page > .agg-view { order: 3; }
  .kahveler-page > .agg-listlink,
  .kahveler-page > .cat-cetvel,
  .kahveler-page > .agg-grid { order: 4; }
  .kahveler-page > .agg-disclaimer,
  .kahveler-page > .agg-trust { order: 8; }
  .kahveler-page > .agg-disclaimer { padding-top: 1.5rem; }

  /* Touch targets ≥ 44px — filtre + katalog aksiyonları */
  .filter-pill, .agg-cmp { min-height: 44px; }
  .agg-go { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
}

@media (max-width: 480px) {
  .page-header, .filter-bar { padding-left: 1.25rem; padding-right: 1.25rem; }
  .collection-grid { padding: 0 1.25rem 1.25rem; }
}

/* ============================================================================
   CETVEL GÖRÜNÜMÜ (30 Ağu 2026) — katalogun ikinci okunuşu
   Kart keşif yüzeyi, cetvel kıyas yüzeyi. Küme aynı, hüküm aynı (core.js
   kfUnitComparable · kfValuePos); değişen yalnız düzen.

   İMZA: medyan sayfa boyunca KESİNTİSİZ tek dikey çizgi. Kartta bu imkânsız —
   her kart kendi `.vrail__datum`ını basar, 24 kart 24 ayrı referans demektir.
   Emsal: yeşil kahve ithalatçısı teklif föyü ("Fiyat = piyasa + fark"; piyasa
   tüm satırlarda sabit, okuyucunun taradığı sütun farktır).
   Gerekçe + alınmayanlar: .claude/data/arastirma.json → cetvel-2026-08.

   ⚠️ SÜTUN ŞABLONU TEK YERDE (`--cat-cols`). Başlık, satır ve ayak onu paylaşır;
   üçünden birine ayrı bir şablon yazmak, başlığın sütunundan kayması demektir.
   ============================================================================ */
.cat-cetvel {
  --cat-rail: 190px;
  --cat-cols: 13ch minmax(0, 1fr) 10ch 8ch 7ch var(--cat-rail) 8ch;
  border-top: 1px solid var(--border-2);
  /* Sol pay komşularla BİREBİR (2.5rem: .agg-count · .agg-trust · .agg-grid).
     İlk çekimde cetvel kapsayıcının payından kaçıp sayfa kenarına yapışmıştı;
     yanındaki "ORGANİK" rozetiyle 40px kayıktı. */
  padding: 1.5rem 2.5rem 4rem;
  /* ⚠️ SAĞ PAY DAHA GENİŞ, ve sebebi estetik değil: Kavruk/⌘K rayı `position:fixed`
     ile `right:2rem`te duruyor ve ~40px yer kaplıyor. Cetvelin en sağdaki sütunu
     yüzeyin en önemli sayısı (₺/100g); ilk çekimde iki satırın sayısı FAB'ın altında
     kaldı. Kart ızgarasında da aynı çakışma var (ayrı iş, HANDOFF'ta kayıtlı) — orayı
     bu turda değiştirmiyorum, ama yeni yüzeyi bozuk doğurmuyorum. */
}
@media (min-width: 901px) { .cat-cetvel { padding-right: 5rem; } }
.cat-cetvel__hd,
.cat-cetvel__foot,
.cat-row {
  display: grid;
  grid-template-columns: var(--cat-cols);
  align-items: center;
  gap: 0.9rem;
  padding: 0.5rem 0.4rem;
  font-family: var(--font-m);
  font-size: 0.72rem;
}
.cat-cetvel__hd {
  color: var(--muted); font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
  border-bottom: 1px solid var(--border-2); padding-bottom: 0.5rem;
}
/* Ray sütununun başlığı yok, ETİKETİ var: sütunu referansı adlandırır (föyün kendi
   hamlesi — fark sütunu "differential" diye değil, referansıyla okunur). */
.cat-cetvel__hd > :nth-child(6) { text-align: center; }
.cat-cetvel__hd > :nth-child(6)::after { content: 'medyan'; }

/* ⚠️ Uzun listenin her satırında `border-top` + `border-bottom` YOK, yalnız alt
   kenarlık (taste §9.F). */
.cat-row { border-bottom: 1px solid rgba(232, 226, 214, 0.06); }
.cat-row:hover { background: rgba(232, 226, 214, 0.035); }
.cat-row--out { opacity: 0.62; }
/* Hücre sarmalayıcısı: grid'in çocuğu HER ZAMAN bu. `min-width:0` olmadan grid'in
   otomatik asgari boyu min-content'tir ve uzun bir kahve adı sütunu genişletip
   satırı taşırır (kartta ödenmiş ders, .agg-card yorumuna bak). */
.cat-row__c { min-width: 0; display: block; overflow: hidden; }
.cat-row__brand {
  display: block;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.6rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none;
}
.cat-row__brand:hover { color: var(--cream-dim); }
.cat-row__name {
  display: block;
  font-family: var(--font-b); font-size: 0.85rem; color: var(--cream); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cat-row__name:hover { color: var(--pop); }
.cat-row__out {
  display: block; font-family: var(--font-m); font-size: 0.58rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted-2);
}
.cat-row__origin {
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.6rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cat-row__num { text-align: right; font-variant-numeric: tabular-nums; color: var(--cream-dim); }
.cat-row__unit { text-align: right; font-variant-numeric: tabular-nums; color: var(--cream); font-weight: 600; }

/* --- Ray + omurga -----------------------------------------------------------
   Hücre HER satırda basılır (kıyasa girmeyen üründe de): `::before` çizgisi
   hücrenin kendisine ait ve satırlar üst üste gelince tek sürekli çizgi oluyor.
   `bottom: -1px` satırın alt kenarlığını da örter — yoksa çizgi her satır
   sınırında 1px kesilir ve "kesintisiz" iddiası kelime olarak kalır. */
.cat-row__rail {
  /* ⚠️ `overflow: visible`: bu hücre hem `.cat-row__c` (kırpar) hem ray. Omurga
     `::before` satırın dışına taşarak komşusuyla birleşiyor; kırpılırsa çizgi her
     satırda kesilir ve "kesintisiz" iddiası yalnız yorumda kalır. */
  overflow: visible;
  position: relative; height: 9px;
  background: linear-gradient(var(--border-2), var(--border-2)) 0 50%/100% 1px no-repeat;
}
.cat-row__rail::before {
  content: ''; position: absolute; left: 50%; margin-left: -0.5px;
  top: -0.5rem; bottom: calc(-0.5rem - 1px); width: 1px;
  background: var(--muted); opacity: 0.55;
}
/* Bu kahvenin yeri. Renk KODU kartla birebir (5 Ağu kilidi): medyan altı --save,
   üstü/eşiti --muted. Konum tek başına anlamı taşır, renk yardımcı kanal. */
.cat-row__tick {
  position: absolute; top: 50%; left: 50%; width: 6px; height: 6px; margin: -3px 0 0 -3px;
  background: var(--save); border-radius: 1px; box-shadow: 0 0 7px -1px var(--save); z-index: 1;
}
.cat-row__tick.is-up, .cat-row__tick.is-flat { background: var(--muted); box-shadow: none; }
/* Kıyasa girmeyen ürün: çizgi geçer (piyasa yine oradadır) ama işaret yok.
   Metin SOLA yaslı — ortada olsaydı çizgi harflerin arasından geçerdi. */
.cat-row__na {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  font-size: 0.6rem; letter-spacing: 0.06em; color: var(--muted-2);
  background: var(--bg); padding-right: 0.4rem; text-decoration: none; white-space: nowrap;
}
.cat-row__na:hover { color: var(--cream-dim); }

/* Medyan ayağı = föyün "calculations footer"ı: sayfadaki dikey çizginin sayısal
   karşılığı, aynı hükümden (kfMedianUnit). Yalnız kıyaslanabilir ürün varken
   basılır — hiçbir satır kıyasa girmiyorsa sayı tutulmayan bir söz olur (6 Ağu). */
.cat-cetvel__foot {
  border-top: 1px solid var(--border-2); color: var(--muted);
  font-size: 0.68rem; padding-top: 0.75rem;
}
.cat-cetvel__foot b { color: var(--pop); font-variant-numeric: tabular-nums; font-weight: 600; }

/* --- Görünüm anahtarı ------------------------------------------------------- */
.agg-view {
  display: flex; align-items: center; gap: 0.5rem;
  /* Yatay pay komşularla birebir (2.5rem) — ilk çekimde "GÖRÜNÜM" etiketi
     sayfa kenarına yapışıp kırpılmıştı. */
  margin: 0.9rem 0 0; padding: 0 2.5rem;
  font-family: var(--font-m); font-size: 0.65rem;
}
.agg-view__k { color: var(--muted-2); letter-spacing: 0.14em; text-transform: uppercase; }
.agg-view__b {
  font: inherit; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); background: none; border: 1px solid var(--border);
  border-radius: 2px; padding: 0.25rem 0.6rem; cursor: pointer;
  transition: color var(--dur-2), border-color var(--dur-2);
}
.agg-view__b:hover { color: var(--cream-dim); border-color: var(--border-2); }
.agg-view__b.is-on { color: var(--bg); background: var(--pop); border-color: var(--pop); }

/* --- MOBİL (≤900px) — açıkça bildirilir, varsayılmaz -------------------------
   7 sütunlu bir föy 360px'te okunmaz: ilk ölçümde kahve ADI sütunu tamamen düştü
   ve ₺/100g ekran dışına taştı. Satır iki bloğa kırılır, ray TAM GENİŞLİĞE geçer —
   bütün raylar hâlâ aynı x aralığını paylaştığı için omurga hayatta kalır. İmza
   mobilde kaybolmuyor, taşınıyor. */
@media (max-width: 900px) {
  .cat-cetvel { --cat-cols: 1fr auto; }
  .cat-cetvel__hd { display: none; }
  .cat-row { grid-auto-rows: auto; gap: 0.25rem 0.6rem; padding: 0.7rem 0.4rem; }
  /* Sıralama KONUMA göre: hücrelerin hepsi aynı sarmalayıcı, dolayısıyla nth-child
     güvenilir. Sınıfa göre yazılsaydı iç öğe ile hücre karışır (bir kez karıştı). */
  .cat-row > :nth-child(2) { order: 0; grid-column: 1 / -1; }        /* kahve adı */
  .cat-row > :nth-child(1) { order: 1; }                             /* marka */
  .cat-row > :nth-child(3) { order: 2; text-align: right; }          /* menşei */
  .cat-row > :nth-child(4) { order: 3; text-align: left; }           /* gramaj */
  .cat-row > :nth-child(5) { order: 4; }                             /* fiyat */
  .cat-row > :nth-child(6) { order: 9; grid-column: 1 / -1; margin-top: 0.4rem; }  /* ray */
  .cat-row > :nth-child(7) { order: 10; grid-column: 1 / -1; }       /* ₺/100g */
  .cat-row__name { white-space: normal; font-size: 0.9rem; }
  .cat-row__num { font-size: 0.66rem; color: var(--muted); }
  .cat-row__unit { font-size: 0.82rem; }
  .cat-cetvel__foot { grid-template-columns: 1fr auto; }
  .cat-cetvel__foot > span:empty { display: none; }
}
