divan/TajikGanjoor/wwwroot/css/tajik-ganjoor.css
2026-09-12 13:24:45 +03:30

860 lines
19 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ==========================================================================
TajikGanjoor typography & layout
Self-hosted fonts: PT Serif (poem/body text) + PT Sans (UI chrome).
Subset used: cyrillic-ext — the plain "cyrillic" subset is MISSING the
six Tajik-specific letters (ғ ӣ қ ӯ ҳ ҷ), cyrillic-ext has them.
========================================================================== */
@font-face {
font-family: 'PT Serif';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/ptserif/pt-serif-cyrillic-ext-400-normal.woff2') format('woff2');
}
@font-face {
font-family: 'PT Serif';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url('/fonts/ptserif/pt-serif-cyrillic-ext-400-italic.woff2') format('woff2');
}
@font-face {
font-family: 'PT Serif';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/ptserif/pt-serif-cyrillic-ext-700-normal.woff2') format('woff2');
}
@font-face {
font-family: 'PT Serif';
font-style: italic;
font-weight: 700;
font-display: swap;
src: url('/fonts/ptserif/pt-serif-cyrillic-ext-700-italic.woff2') format('woff2');
}
@font-face {
font-family: 'PT Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/ptsans/pt-sans-cyrillic-ext-400-normal.woff2') format('woff2');
}
@font-face {
font-family: 'PT Sans';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url('/fonts/ptsans/pt-sans-cyrillic-ext-400-italic.woff2') format('woff2');
}
@font-face {
font-family: 'PT Sans';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/ptsans/pt-sans-cyrillic-ext-700-normal.woff2') format('woff2');
}
@font-face {
font-family: 'PT Sans';
font-style: italic;
font-weight: 700;
font-display: swap;
src: url('/fonts/ptsans/pt-sans-cyrillic-ext-700-italic.woff2') format('woff2');
}
/* Persian original text (interlinear comparison lines) - Cyrillic fonts above have no
Arabic-script glyphs at all, so this needs its own font. Vazirmatn is the same font
the main ganjoor.net site self-hosts for Persian, reused here for a consistent,
recognizable feel across the two sites. */
@font-face {
font-family: 'Vazirmatn';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/vazirmatn/vazirmatn-arabic-400-normal.woff2') format('woff2');
}
@font-face {
font-family: 'Vazirmatn';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('/fonts/vazirmatn/vazirmatn-arabic-700-normal.woff2') format('woff2');
}
/* ---------- base page: warm paper tone, PT Sans chrome ---------- */
:root {
--tg-paper: #faf6ee;
--tg-paper-edge: #efe6d3;
--tg-surface: #ffffff;
--tg-ink: #2b2620;
--tg-ink-soft: #5b5346;
--tg-accent: #8a5a2b;
--tg-accent-deep: #6b3f1d;
--tg-rule: #d9cdb2;
}
@media (prefers-color-scheme: dark) {
:root {
--tg-paper: #211d18;
--tg-paper-edge: #2c2620;
--tg-surface: #2c2620;
--tg-ink: #ece6d9;
--tg-ink-soft: #bfb6a4;
--tg-accent: #d1a06a;
--tg-accent-deep: #e3b988;
--tg-rule: #453d32;
}
/* poet portrait circles keep a light backing regardless of theme -
the portraits are illustrations on a light background, and a
pure-white disc reads as a deliberate frame against the dark
page rather than a mismatched surface */
.tg-poet-portrait,
.tg-poet-portrait-lg,
.sitem-poet-portrait,
.tg-crumb-poet img {
background: #f4efe4;
}
}
html, body {
background-color: var(--tg-paper);
color: var(--tg-ink);
font-family: 'PT Sans', Tahoma, sans-serif;
}
.navbar {
background-color: var(--tg-paper) !important;
border-bottom: 1px solid var(--tg-rule) !important;
font-family: 'PT Sans', sans-serif;
}
/* BreadCrumpUrls always starts with <a href="/">Ганҷур</a> (see Index.cshtml.cs) -
style that first link as the site's wordmark rather than duplicating it. */
.tg-breadcrumb {
font-family: 'PT Sans', sans-serif;
font-size: 0.95rem;
display: flex;
flex-wrap: wrap;
align-items: center;
column-gap: 4px;
row-gap: 2px;
}
.tg-breadcrumb a:first-child {
font-family: 'PT Serif', serif;
font-weight: 700;
font-size: 1.3rem;
color: var(--tg-accent-deep);
text-decoration: none;
margin-inline-end: 4px;
}
.navbar input[type="search"] {
font-family: 'PT Sans', sans-serif;
border: 1px solid var(--tg-rule);
background: var(--tg-surface);
color: var(--tg-ink);
}
.footer {
font-family: 'PT Sans', sans-serif;
font-size: 0.85rem;
}
.footer a {
color: var(--tg-accent-deep);
}
/* ---------- poem prev/next navigation ---------- */
.tg-poem-nav {
display: flex;
justify-content: space-between;
align-items: stretch;
gap: 12px;
max-width: 720px;
margin: 24px auto 8px auto;
padding-top: 14px;
border-top: 1px solid var(--tg-rule);
}
.tg-poem-nav-link {
display: flex;
align-items: center;
gap: 8px;
max-width: 46%;
padding: 6px 10px;
text-decoration: none;
color: var(--tg-ink-soft);
border-radius: 6px;
}
.tg-poem-nav-link:hover {
background-color: var(--tg-paper-edge);
color: var(--tg-accent-deep);
}
.tg-poem-nav-next {
margin-inline-start: auto;
text-align: end;
flex-direction: row-reverse;
}
.tg-poem-nav-arrow {
font-size: 1.1rem;
flex: 0 0 auto;
}
.tg-poem-nav-text {
display: flex;
flex-direction: column;
min-width: 0;
}
.tg-poem-nav-caption {
font-family: 'PT Sans', sans-serif;
font-size: 0.72rem;
opacity: 0.75;
}
.tg-poem-nav-title {
font-family: 'PT Serif', serif;
font-size: 0.95rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ---------- poem page: printed-book feel ---------- */
.container {
max-width: 720px;
}
.b, .b2, .n, .l {
font-family: 'PT Serif', serif;
}
/* one beyt (couplet): two stacked mesras, book-style, not side-by-side
columns — matches how Cyrillic verse is actually typeset (and matches
ganjoor.net's own <768px fallback), and needs no breakpoint since it's
already a single column at any width. */
.b {
max-width: 480px;
margin: 0 auto 1.35em auto;
text-align: center;
clear: both;
}
.b .m1, .b .m2 {
float: none;
width: auto;
display: block;
}
.b .m1 p, .b .m2 p {
font-family: 'PT Serif', serif;
font-weight: 400;
font-size: 1.15rem;
line-height: 1.9;
margin: 0;
text-shadow: none;
text-align: center;
}
.b .m2 p {
opacity: 0.92;
}
/* rubaʼi-style already-centered couplet */
.b2 p {
font-family: 'PT Serif', serif;
font-size: 1.15rem;
line-height: 1.9;
text-align: center;
margin: 0;
}
/* paragraph / single-line verses */
.n p, .l p {
font-family: 'PT Serif', serif;
font-size: 1.1rem;
line-height: 1.9;
text-align: center;
margin: 0 auto 1.2em auto;
max-width: 560px;
}
/* comments / notes: quieter, sans-serif, clearly not part of the poem */
.c {
max-width: 90%;
margin: 10px auto;
padding: 8px 14px;
background-color: var(--tg-paper-edge);
border-inline-start: 3px solid var(--tg-accent);
clear: both;
}
.c p {
font-family: 'PT Sans', sans-serif;
font-size: 0.85rem;
color: var(--tg-ink-soft);
margin: 0;
}
/* Persian original, shown interlinear directly beneath its Tajik line (per
verse.OriginalText - see PrepareBilingualHtmlText). Deliberately smaller
and quieter than the Tajik line above it: this is a Tajik-first site, the
Persian is a reference/comparison aid, not the primary reading text.
Selectors repeat the base verse rules' specificity + the .tg-fa class so
this reliably wins regardless of source order. */
.b .m1 p.tg-fa,
.b .m2 p.tg-fa,
.b2 p.tg-fa,
.n p.tg-fa,
.l p.tg-fa,
.c p.tg-fa {
font-family: 'Vazirmatn', Tahoma, sans-serif;
font-size: 0.82em;
line-height: 1.7;
color: var(--tg-ink-soft);
opacity: 0.85;
margin: 0.2em 0 0 0;
unicode-bidi: isolate;
}
/* poem title */
.text-center h1, .text-center h2 {
font-family: 'PT Serif', serif;
font-weight: 700;
color: var(--tg-accent-deep);
}
.text-center h1 a, .text-center h2 a {
color: inherit;
text-decoration: none;
}
/* faint rule between poems on a listing/category page */
.item {
padding-top: 20px;
border-top: 1px solid var(--tg-rule);
margin-top: 20px;
}
.item:first-child {
border-top: none;
margin-top: 0;
}
/* search hit highlighting - keep legible on the paper background */
.hilite, .hilite1, .hilite2, .hilite3 {
padding: 0 2px;
border-radius: 2px;
}
/* ---------- homepage: poet card grid ---------- */
.tg-poet-grid {
max-width: 980px;
margin: 10px auto 0 auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 18px 12px;
padding: 0 8px;
}
.tg-poet-card {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
color: var(--tg-ink);
}
.tg-poet-card .tg-poet-portrait {
width: 84px;
height: 84px;
border-radius: 50%;
overflow: hidden;
border: 2px solid var(--tg-rule);
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
.tg-poet-card .tg-poet-portrait img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.tg-poet-card .tg-poet-name {
margin-top: 8px;
font-family: 'PT Serif', serif;
font-size: 0.92rem;
text-align: center;
line-height: 1.25;
}
.tg-poet-card:hover .tg-poet-portrait {
border-color: var(--tg-accent);
}
.tg-poet-card:hover .tg-poet-name {
color: var(--tg-accent-deep);
}
@media (max-width: 480px) {
.tg-poet-grid {
grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
gap: 14px 8px;
}
.tg-poet-card .tg-poet-portrait {
width: 64px;
height: 64px;
}
.tg-poet-card .tg-poet-name {
font-size: 0.8rem;
}
}
/* ---------- poet bio page ---------- */
.tg-poet-header {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 18px;
}
.tg-poet-header .tg-poet-portrait-lg {
width: 128px;
height: 128px;
border-radius: 50%;
overflow: hidden;
border: 3px solid var(--tg-rule);
background: #fff;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12);
}
.tg-poet-header .tg-poet-portrait-lg img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
/* small poet portrait inlined into the breadcrumb, prefixing the poet's
name wherever it appears there (poet page's own crumb, and the first
ancestor crumb on category/poem pages, which is always the poet's root
category - see Index.cshtml.cs) */
.tg-crumb-poet {
display: inline-flex;
align-items: center;
gap: 5px;
vertical-align: middle;
}
.tg-crumb-poet img {
width: 22px;
height: 22px;
border-radius: 50%;
object-fit: cover;
border: 1px solid var(--tg-rule);
background: #fff;
vertical-align: middle;
flex: 0 0 auto;
}
/* GanjoorPage.HtmlText for poet/cat pages is server-generated plain
<p> tags (bio prose) followed by more <p><a>...</a></p> tags (sub-
category / poem links) with no distinguishing classes at all - the
markup is identical for both, so it's told apart here structurally:
a paragraph whose only content is a single link is a nav row, any
other paragraph is bio prose. */
.tg-poet-page p,
.tg-cat-page p {
font-family: 'PT Serif', serif;
font-size: 1.05rem;
line-height: 1.85;
text-align: start;
margin: 0 auto 0.9em auto;
max-width: 620px;
}
.tg-poet-page p:has(> a:only-child),
.tg-cat-page p:has(> a:only-child) {
font-family: 'PT Sans', sans-serif;
font-size: 1rem;
text-align: start;
margin: 0;
padding: 10px 14px;
border-bottom: 1px solid var(--tg-rule);
max-width: 620px;
line-height: 1.6;
}
.tg-poet-page p:has(> a:only-child):first-of-type,
.tg-cat-page p:has(> a:only-child):first-of-type {
border-top: 1px solid var(--tg-rule);
margin-top: 12px;
}
.tg-poet-page p:has(> a:only-child) a,
.tg-cat-page p:has(> a:only-child) a {
color: var(--tg-accent-deep);
text-decoration: none;
font-weight: 700;
}
/* the excerpt trailing the link (": ..." from PrepareTajikCatHtmlTextAsync /
PrepareTajikPoetHtmlTextAsync) is plain text in the same <p>, so it can only
be dimmed via the paragraph's own color - the link's explicit color above
still wins for the title itself */
.tg-poet-page p:has(> a:only-child),
.tg-cat-page p:has(> a:only-child) {
color: var(--tg-ink-soft);
}
.tg-poet-page p:has(> a:only-child):hover,
.tg-cat-page p:has(> a:only-child):hover {
background-color: var(--tg-paper-edge);
}
/* ---------- search results ---------- */
.sitem {
max-width: 620px;
margin: 0 auto;
padding: 16px 4px;
border-top: 1px solid var(--tg-rule);
text-align: start;
display: flex;
gap: 14px;
align-items: flex-start;
}
.sitem:first-of-type {
border-top: none;
}
.sitem-poet-portrait {
flex: 0 0 auto;
display: block;
width: 52px;
height: 52px;
border-radius: 50%;
overflow: hidden;
border: 2px solid var(--tg-rule);
background: #fff;
}
.sitem-poet-portrait img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.sitem-poet-portrait:hover {
border-color: var(--tg-accent);
}
.sitem-body {
flex: 1 1 auto;
min-width: 0;
}
.sitem h2 {
font-family: 'PT Serif', serif;
font-size: 1.15rem;
font-weight: 700;
margin-bottom: 6px;
}
.sitem h2 a {
color: var(--tg-accent-deep);
text-decoration: none;
}
.sit {
float: none;
max-width: none;
font-family: 'PT Serif', serif;
font-size: 0.98rem;
line-height: 1.8;
color: var(--tg-ink-soft);
}
.sit p {
margin: 0 0 4px 0;
}
@media (max-width: 420px) {
.sitem-poet-portrait {
width: 40px;
height: 40px;
}
}
/* ---------- pagination bar (GeneratePagingBarHtml in Index.cshtml.cs) ---------- */
.circled-number, .circled-number-diff {
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
margin: 2px;
border-radius: 50%;
font-family: 'PT Sans', sans-serif;
font-size: 0.9rem;
text-decoration: none;
}
.circled-number {
border: 1px solid var(--tg-rule);
color: var(--tg-ink-soft);
}
.circled-number:hover {
border-color: var(--tg-accent);
color: var(--tg-accent-deep);
}
.circled-number-diff {
background-color: var(--tg-accent-deep);
color: #fff;
}
/* ---------- homepage: century grouping + inline poet search ---------- */
.tg-century-heading {
max-width: 980px;
margin: 28px auto 4px auto;
padding: 0 8px;
font-family: 'PT Serif', serif;
font-weight: 700;
font-size: 1.05rem;
color: var(--tg-accent-deep);
text-align: start;
border-bottom: 1px solid var(--tg-rule);
padding-bottom: 6px;
}
.tg-century-nav {
max-width: 980px;
margin: 8px auto 0 auto;
padding: 0 8px;
text-align: center;
}
.tg-poet-search {
max-width: 480px;
margin: 20px auto 0 auto;
padding: 0 8px;
}
.tg-poet-search input {
width: 100%;
padding: 8px 12px;
font-family: 'PT Sans', sans-serif;
font-size: 0.95rem;
border: 1px solid var(--tg-rule);
border-radius: 6px;
background: var(--tg-surface);
color: var(--tg-ink);
}
.tg-poet-search input:focus {
outline: none;
border-color: var(--tg-accent);
}
/* search results grid only takes up space once populated by tgInlineSearch (site.js) */
.tg-poet-search .tg-poet-grid:empty {
margin: 0;
}
.tg-poet-search .tg-poet-grid {
margin-top: 14px;
}
/* century-grouped vs. alphabetical homepage view switch */
.tg-view-switch {
display: flex;
justify-content: center;
gap: 8px;
max-width: 480px;
margin: 18px auto 0 auto;
padding: 0 8px;
}
.tg-view-switch-btn {
font-family: 'PT Sans', sans-serif;
font-size: 0.9rem;
padding: 7px 16px;
border: 1px solid var(--tg-rule);
border-radius: 20px;
background: var(--tg-surface);
color: var(--tg-ink-soft);
cursor: pointer;
}
.tg-view-switch-btn:hover {
border-color: var(--tg-accent);
color: var(--tg-accent-deep);
}
.tg-view-switch-btn.active {
background: var(--tg-accent-deep);
border-color: var(--tg-accent-deep);
color: #fff;
}
/* ---------- error page ---------- */
.text-danger {
font-family: 'PT Serif', serif;
color: var(--tg-accent-deep) !important;
}
/* ---------- poem recitations (audio) ---------- */
.tg-recitations {
max-width: 560px;
margin: 28px auto 0 auto;
padding-top: 16px;
border-top: 1px solid var(--tg-rule);
text-align: start;
}
.tg-recitations-title {
font-family: 'PT Serif', serif;
font-weight: 700;
font-size: 1rem;
color: var(--tg-accent-deep);
margin-bottom: 10px;
}
.tg-recitation {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
padding: 10px 12px;
margin-bottom: 8px;
background-color: var(--tg-paper-edge);
border-radius: 8px;
}
.tg-recitation audio {
max-width: 100%;
height: 34px;
}
.tg-recitation-caption {
font-family: 'PT Sans', sans-serif;
font-size: 0.88rem;
color: var(--tg-ink-soft);
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.tg-recitation-title {
color: var(--tg-ink);
}
.tg-recitation-download {
color: var(--tg-accent-deep);
text-decoration: none;
margin-inline-start: 4px;
}
.tg-recitation-download:hover {
opacity: 0.7;
}
@media (max-width: 480px) {
.tg-recitation audio {
width: 100%;
}
}
/* verse currently being recited, highlighted by recitation-sync.js */
.tg-verse-active {
color: var(--tg-accent-deep) !important;
background-color: var(--tg-paper-edge);
border-radius: 4px;
transition: background-color 0.2s ease;
}
/* ---------- sticky mini audio-player (recitation seek controls stay
reachable while scrolling the poem text) ---------- */
.tg-sticky-player {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 14px;
background: var(--tg-paper-edge);
border-top: 1px solid var(--tg-rule);
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
}
.tg-sticky-player-narrator {
font-weight: 600;
white-space: nowrap;
color: var(--tg-ink);
flex-shrink: 0;
}
.tg-sticky-player-audio-slot {
flex: 1;
min-width: 0;
}
.tg-sticky-player-audio-slot audio {
width: 100%;
display: block;
}
.tg-sticky-player-btn {
display: inline-flex;
align-items: center;
cursor: pointer;
color: var(--tg-ink);
padding: 4px 6px;
flex-shrink: 0;
}
.tg-sticky-player-btn:hover {
color: var(--tg-accent);
}
@media (max-width: 600px) {
.tg-sticky-player-narrator {
display: none;
}
}