pandorga 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +77 -0
- data/DESIGN.md +1434 -0
- data/LICENSE +21 -0
- data/README.md +81 -0
- data/_data/themes/dark.yml +97 -0
- data/_data/themes/light.yml +120 -0
- data/_data/themes/shared.yml +37 -0
- data/_data/translations.yml +85 -0
- data/_includes/chord-tab.html +38 -0
- data/_includes/content-runtime/00-config.html +22 -0
- data/_includes/content-runtime/10-utils.html +176 -0
- data/_includes/content-runtime/20-markdown.html +264 -0
- data/_includes/content-runtime/25-code-blocks.html +315 -0
- data/_includes/content-runtime/30-includes-bib.html +190 -0
- data/_includes/content-runtime/30-includes-xcite.html +122 -0
- data/_includes/content-runtime/30-includes.html +365 -0
- data/_includes/content-runtime/40-listing.html +225 -0
- data/_includes/content-runtime/41-listing-helpers.html +71 -0
- data/_includes/content-runtime/42-listing-filter.html +208 -0
- data/_includes/content-runtime/43-blocks.html +379 -0
- data/_includes/content-runtime/50-detail.html +861 -0
- data/_includes/content-runtime/55-toc.html +176 -0
- data/_includes/content-runtime/60-fragments.html +567 -0
- data/_includes/content-runtime/90-bootstrap.html +76 -0
- data/_includes/cut-in.html +10 -0
- data/_includes/cv/cv-box.html +18 -0
- data/_includes/dict-card.html +24 -0
- data/_includes/figure.html +36 -0
- data/_includes/home/band-index.html +43 -0
- data/_includes/home/band-listing.html +49 -0
- data/_includes/mathjax.html +10 -0
- data/_includes/ongoing-product.html +1 -0
- data/_includes/page/content-runtime.html +20 -0
- data/_includes/page/date_evolution.html +19 -0
- data/_includes/page/figure-lightbox.html +102 -0
- data/_includes/page/formatted_date.html +15 -0
- data/_includes/page/hero-default.html +18 -0
- data/_includes/page/listing-runtime-attrs.html +8 -0
- data/_includes/page/mermaid.html +101 -0
- data/_includes/page/network-graph.html +1253 -0
- data/_includes/page/page-header.html +41 -0
- data/_includes/page/professional-connections.html +2 -0
- data/_includes/page/site-footer.html +101 -0
- data/_includes/page/timeline-section.html +868 -0
- data/_includes/plotly.html +22 -0
- data/_includes/theme/dev-reexport.html +100 -0
- data/_includes/theme/favicons.html +4 -0
- data/_includes/theme/font-loader.html +55 -0
- data/_includes/theme/shell-theme-boot.html +115 -0
- data/_includes/theme/site-logo.html +6 -0
- data/_includes/theme/tailwind-theme-colors.json.liquid +65 -0
- data/_includes/theme/tailwind-theme-fonts.json.liquid +6 -0
- data/_includes/theme/theme-context.liquid +20 -0
- data/_includes/theme/theme-toggle.html +94 -0
- data/_includes/theme/theme-vars-block.liquid +161 -0
- data/_includes/theme/theme-vars.html +16 -0
- data/_includes/transcription.html +80 -0
- data/_includes/tweet.html +22 -0
- data/_includes/video.html +11 -0
- data/_includes/xcite.html +3 -0
- data/_includes/youtube-short.html +26 -0
- data/_includes/youtube.html +12 -0
- data/_layouts/article.html +27 -0
- data/_layouts/articles.html +534 -0
- data/_layouts/bibliography.html +417 -0
- data/_layouts/blog.html +544 -0
- data/_layouts/cv.html +393 -0
- data/_layouts/home.html +319 -0
- data/_layouts/network.html +9 -0
- data/_layouts/pandorga/articles.html +4 -0
- data/_layouts/pandorga/bibliography.html +4 -0
- data/_layouts/pandorga/blog.html +4 -0
- data/_layouts/pandorga/cv.html +4 -0
- data/_layouts/pandorga/media.html +4 -0
- data/_layouts/pandorga/network.html +4 -0
- data/_layouts/pandorga/portfolio.html +4 -0
- data/_layouts/post.html +7 -0
- data/_layouts/product.html +5 -0
- data/_layouts/project.html +27 -0
- data/_layouts/projects.html +534 -0
- data/_layouts/resources.html +387 -0
- data/_layouts/shell.html +203 -0
- data/_layouts/text.html +246 -0
- data/_plugins/bibliography_artifact.rb +57 -0
- data/_plugins/content_backend.rb +37 -0
- data/_plugins/content_collections.rb +51 -0
- data/_plugins/content_detail_paths.rb +58 -0
- data/_plugins/content_headers.rb +73 -0
- data/_plugins/content_keys.rb +310 -0
- data/_plugins/content_local_serve.rb +168 -0
- data/_plugins/content_site_adapter.rb +159 -0
- data/_plugins/content_validators_hook.rb +20 -0
- data/_plugins/content_writing_index.rb +52 -0
- data/_plugins/content_writing_paths.rb +55 -0
- data/_plugins/force_utf8_encoding.rb +13 -0
- data/_plugins/git_chronology.rb +211 -0
- data/_plugins/git_metadata.rb +43 -0
- data/_plugins/job_sections.rb +25 -0
- data/_plugins/lib/content_validators.rb +27 -0
- data/_plugins/lib/resource_validator.rb +56 -0
- data/_plugins/lib/tag_validator.rb +153 -0
- data/_plugins/lib/text_excerpt.rb +56 -0
- data/_plugins/lib/writing_entry.rb +107 -0
- data/_plugins/local_detail_rewrites.rb +194 -0
- data/_plugins/timeline.rb +507 -0
- data/_plugins/writing_slug_limits.rb +70 -0
- data/assets/css/article.css +1330 -0
- data/assets/css/base.css +1432 -0
- data/assets/css/cv.css +13 -0
- data/assets/css/global-link.css +94 -0
- data/assets/css/ledger/bibliography.css +307 -0
- data/assets/css/ledger/chrome.css +118 -0
- data/assets/css/ledger/cv.css +836 -0
- data/assets/css/ledger/detail.css +1270 -0
- data/assets/css/ledger/footer.css +298 -0
- data/assets/css/ledger/home.css +1490 -0
- data/assets/css/ledger/network.css +106 -0
- data/assets/css/ledger/projects.css +716 -0
- data/assets/css/ledger/rascunhos.css +379 -0
- data/assets/css/ledger/sources.css +327 -0
- data/assets/css/ledger/writing.css +754 -0
- data/assets/tailwind-play.js +15 -0
- data/examples/full/Gemfile +7 -0
- data/examples/full/_config.yml +92 -0
- data/examples/full/_redirects +3 -0
- data/examples/full/content/collections/articles/2026-01-01-welcome.md +9 -0
- data/examples/full/content/collections/data/contacts.yml +3 -0
- data/examples/full/content/collections/data/education.yml +4 -0
- data/examples/full/content/collections/jobs/research-fellow.md +12 -0
- data/examples/full/content/collections/posts/2026-01-02-note.md +9 -0
- data/examples/full/content/collections/products/ledger-tool.md +6 -0
- data/examples/full/content/collections/projects/demo-kit.md +10 -0
- data/examples/full/content/collections/resources/style-guide.md +7 -0
- data/examples/full/content/pages/cv/summary.md +1 -0
- data/examples/full/content/pages/headers.yml +20 -0
- data/examples/full/index.html +4 -0
- data/examples/minimal/Gemfile +7 -0
- data/examples/minimal/_config.yml +47 -0
- data/examples/minimal/_redirects +3 -0
- data/examples/minimal/content/collections/articles/2026-01-01-hello.md +10 -0
- data/examples/minimal/content/collections/articles/2026-01-02-second.md +9 -0
- data/examples/minimal/content/pages/headers.yml +6 -0
- data/examples/minimal/index.html +4 -0
- data/exe/pandorga +7 -0
- data/functions/api/studio/[[path]].js +562 -0
- data/functions/api/studio/_lib/auth.js +131 -0
- data/functions/api/studio/_lib/blocks.js +156 -0
- data/functions/api/studio/_lib/gemini.js +62 -0
- data/functions/api/studio/_lib/github.js +278 -0
- data/functions/api/studio/_lib/guidelines.js +143 -0
- data/functions/api/studio/_lib/paths.js +76 -0
- data/functions/api/studio/_lib/prompts.js +165 -0
- data/functions/api/studio/_lib/rate-limit.js +40 -0
- data/functions/api/studio/_lib/rewrite.js +136 -0
- data/functions/api/studio/_lib/sanitize.js +143 -0
- data/lib/pandorga/cli.rb +66 -0
- data/lib/pandorga/commands/doctor.rb +66 -0
- data/lib/pandorga/commands/export.rb +30 -0
- data/lib/pandorga/commands/install_functions.rb +41 -0
- data/lib/pandorga/commands/new.rb +113 -0
- data/lib/pandorga/commands/publish.rb +53 -0
- data/lib/pandorga/commands/serve.rb +34 -0
- data/lib/pandorga/commands/studio_schema.rb +309 -0
- data/lib/pandorga/jekyll/generator.rb +74 -0
- data/lib/pandorga/jekyll/plugins/bibliography_artifact.rb +57 -0
- data/lib/pandorga/jekyll/plugins/content_backend.rb +37 -0
- data/lib/pandorga/jekyll/plugins/content_collections.rb +51 -0
- data/lib/pandorga/jekyll/plugins/content_detail_paths.rb +58 -0
- data/lib/pandorga/jekyll/plugins/content_headers.rb +73 -0
- data/lib/pandorga/jekyll/plugins/content_keys.rb +310 -0
- data/lib/pandorga/jekyll/plugins/content_local_serve.rb +168 -0
- data/lib/pandorga/jekyll/plugins/content_site_adapter.rb +159 -0
- data/lib/pandorga/jekyll/plugins/content_validators_hook.rb +20 -0
- data/lib/pandorga/jekyll/plugins/content_writing_index.rb +52 -0
- data/lib/pandorga/jekyll/plugins/content_writing_paths.rb +55 -0
- data/lib/pandorga/jekyll/plugins/force_utf8_encoding.rb +13 -0
- data/lib/pandorga/jekyll/plugins/git_chronology.rb +211 -0
- data/lib/pandorga/jekyll/plugins/git_metadata.rb +43 -0
- data/lib/pandorga/jekyll/plugins/job_sections.rb +25 -0
- data/lib/pandorga/jekyll/plugins/lib/content_validators.rb +27 -0
- data/lib/pandorga/jekyll/plugins/lib/resource_validator.rb +56 -0
- data/lib/pandorga/jekyll/plugins/lib/tag_validator.rb +153 -0
- data/lib/pandorga/jekyll/plugins/lib/text_excerpt.rb +56 -0
- data/lib/pandorga/jekyll/plugins/lib/writing_entry.rb +107 -0
- data/lib/pandorga/jekyll/plugins/local_detail_rewrites.rb +194 -0
- data/lib/pandorga/jekyll/plugins/timeline.rb +507 -0
- data/lib/pandorga/jekyll/plugins/writing_slug_limits.rb +70 -0
- data/lib/pandorga/jekyll.rb +15 -0
- data/lib/pandorga/object_store_env.rb +51 -0
- data/lib/pandorga/registry/schema.yml +115 -0
- data/lib/pandorga/registry.rb +279 -0
- data/lib/pandorga/version.rb +5 -0
- data/lib/pandorga.rb +19 -0
- data/scripts/cdn-allowlist.json +19 -0
- data/scripts/content/backfill-content-keys.rb +99 -0
- data/scripts/content/band_art.rb +362 -0
- data/scripts/content/export-content-json.rb +741 -0
- data/scripts/content/flatten-ansi-capture.mjs +153 -0
- data/scripts/content/hero_portraits.rb +28 -0
- data/scripts/content/publish-content-to-object-store.sh +78 -0
- data/scripts/content/publish-content-to-r2.sh +5 -0
- data/scripts/content/sync-content-json-to-r2.rb +167 -0
- data/scripts/content/sync-content-redirects.rb +12 -0
- data/scripts/generate-configuration-doc.rb +127 -0
- data/scripts/lib/content_license.rb +50 -0
- data/scripts/lib/content_storage_config.rb +70 -0
- data/scripts/lib/normalize-display-math.mjs +52 -0
- data/scripts/lib/r2_json_sync.rb +76 -0
- data/scripts/lib/withdrawn_public_objects.rb +23 -0
- data/scripts/lib/writing_index_contract.rb +61 -0
- data/scripts/pdf/md-to-pdf.mjs +1400 -0
- data/scripts/pdf/md-to-pdf.sh +27 -0
- data/scripts/test/fixtures/dual-template/_config.yml +32 -0
- data/scripts/test/fixtures/dual-template/index.html +4 -0
- data/scripts/test/render-parity/article-note.json +5 -0
- data/scripts/test/render-parity/blockquote.json +5 -0
- data/scripts/test/render-parity/blocks/ansi-basic.json +7 -0
- data/scripts/test/render-parity/blocks/ansi-bold-is-bright.json +7 -0
- data/scripts/test/render-parity/blocks/ansi-drops-cursor-moves.json +7 -0
- data/scripts/test/render-parity/blocks/ansi-escapes-markup.json +7 -0
- data/scripts/test/render-parity/blocks/ansi-extended-colour.json +7 -0
- data/scripts/test/render-parity/blocks/ansi-real-control-byte.json +7 -0
- data/scripts/test/render-parity/blocks/archive-card-date-once.json +19 -0
- data/scripts/test/render-parity/blocks/archive-card-empty-foot.json +7 -0
- data/scripts/test/render-parity/blocks/archive-card-footer-dates.json +22 -0
- data/scripts/test/render-parity/blocks/archive-card-meta-parts.json +26 -0
- data/scripts/test/render-parity/blocks/archive-card.json +32 -0
- data/scripts/test/render-parity/blocks/cta-link.json +13 -0
- data/scripts/test/render-parity/blocks/lang-pill-pt.json +8 -0
- data/scripts/test/render-parity/blocks/lang-pill.json +8 -0
- data/scripts/test/render-parity/blocks/ledger-row-meta-parts.json +29 -0
- data/scripts/test/render-parity/blocks/ledger-row.json +35 -0
- data/scripts/test/render-parity/blocks/meta-strip.json +27 -0
- data/scripts/test/render-parity/blocks/poster-media-image.json +8 -0
- data/scripts/test/render-parity/blocks/poster-media-video.json +9 -0
- data/scripts/test/render-parity/blocks/section-banner.json +13 -0
- data/scripts/test/render-parity/blocks/system-card-custom-meta.json +22 -0
- data/scripts/test/render-parity/blocks/system-card.json +48 -0
- data/scripts/test/render-parity/blocks/tag-chips-links.json +12 -0
- data/scripts/test/render-parity/blocks/tag-chips.json +9 -0
- data/scripts/test/render-parity/cut-in-blank-line.json +9 -0
- data/scripts/test/render-parity/cut-in-right.json +9 -0
- data/scripts/test/render-parity/cut-in.json +8 -0
- data/scripts/test/render-parity/figure.json +5 -0
- data/scripts/test/render-parity/load-runtime.mjs +337 -0
- data/scripts/test/render-parity/ongoing-product.json +5 -0
- data/scripts/test/render-parity/plotly.json +5 -0
- data/scripts/test/render-parity/poem.json +5 -0
- data/scripts/test/render-parity/run-absent-field-checks.mjs +232 -0
- data/scripts/test/render-parity/run-block-fixture.mjs +86 -0
- data/scripts/test/render-parity/run-detail-parity-checks.mjs +123 -0
- data/scripts/test/render-parity/run-field-flow-checks.mjs +227 -0
- data/scripts/test/render-parity/run-fixture.mjs +159 -0
- data/scripts/test/render-parity/selectors.mjs +43 -0
- data/scripts/test/render-parity/video.json +5 -0
- data/scripts/test/render-parity/youtube-short.json +10 -0
- data/scripts/test/render-parity/youtube.json +8 -0
- data/scripts/test/test-absent-field-absent-element.rb +43 -0
- data/scripts/test/test-cdn-pins.rb +44 -0
- data/scripts/test/test-cloudflare-watch-paths-doc.rb +31 -0
- data/scripts/test/test-configuration-doc.rb +36 -0
- data/scripts/test/test-content-detail-urls.rb +346 -0
- data/scripts/test/test-content-keys.rb +110 -0
- data/scripts/test/test-content-license.rb +45 -0
- data/scripts/test/test-content-render-parity.rb +38 -0
- data/scripts/test/test-content-validators.rb +12 -0
- data/scripts/test/test-css-structure.rb +72 -0
- data/scripts/test/test-cv-export-contract.rb +158 -0
- data/scripts/test/test-detail-render-parity.rb +40 -0
- data/scripts/test/test-dev-reexport.rb +122 -0
- data/scripts/test/test-doctor.rb +39 -0
- data/scripts/test/test-dual-template-instances.rb +87 -0
- data/scripts/test/test-dual-template-runtime.rb +167 -0
- data/scripts/test/test-examples-build.rb +60 -0
- data/scripts/test/test-export-content-json-incremental.rb +138 -0
- data/scripts/test/test-export.rb +53 -0
- data/scripts/test/test-exported-fields-reach-the-view.rb +60 -0
- data/scripts/test/test-form-control-theming.rb +143 -0
- data/scripts/test/test-git-chronology.rb +414 -0
- data/scripts/test/test-hero-portraits.mjs +97 -0
- data/scripts/test/test-hero-portraits.rb +162 -0
- data/scripts/test/test-home-band-art.rb +135 -0
- data/scripts/test/test-install-functions.rb +39 -0
- data/scripts/test/test-language-export.rb +79 -0
- data/scripts/test/test-listing-filter-contract.rb +119 -0
- data/scripts/test/test-math-row-breaks.mjs +79 -0
- data/scripts/test/test-math-row-breaks.rb +18 -0
- data/scripts/test/test-new.rb +113 -0
- data/scripts/test/test-no-personal-data.rb +85 -0
- data/scripts/test/test-public-cv-export.rb +164 -0
- data/scripts/test/test-r2-config-consistency.rb +57 -0
- data/scripts/test/test-r2-json-sync.rb +193 -0
- data/scripts/test/test-registry-home.rb +34 -0
- data/scripts/test/test-runtime-js-syntax.rb +64 -0
- data/scripts/test/test-slim-writing-index.rb +126 -0
- data/scripts/test/test-studio-api-contract.rb +99 -0
- data/scripts/test/test-studio-content-files.rb +79 -0
- data/scripts/test/test-studio-liquid-roundtrip.mjs +179 -0
- data/scripts/test/test-studio-rate-limit.mjs +70 -0
- data/scripts/test/test-studio-rewrite-api-contract.rb +59 -0
- data/scripts/test/test-studio-rewrite-sanitize.mjs +210 -0
- data/scripts/test/test-studio-schema-composition.rb +126 -0
- data/scripts/test/test-studio-slug-config.rb +167 -0
- data/scripts/test/test-template-packages.rb +51 -0
- data/scripts/test/test-text-excerpt.rb +51 -0
- data/scripts/test/test-unwrap-media-src.mjs +39 -0
- data/scripts/test/test-unwrap-media-src.rb +19 -0
- data/scripts/test/test-withdrawn-content-export.rb +69 -0
- data/scripts/test/test-writing-index-export-slugs.rb +84 -0
- data/scripts/test/test-writing-slug-limits.rb +61 -0
- data/scripts/test/test-xcite-chronology.rb +106 -0
- data/scripts/validate.sh +74 -0
- data/scripts/visual/build-cv-pages-json.js +33 -0
- data/scripts/visual/build-site-pages-json.js +94 -0
- data/scripts/visual/publish-visual-inspection-to-r2.sh +42 -0
- data/scripts/visual/take-screenshots.js +88 -0
- data/scripts/visual/visual-inspection-pages.json +113 -0
- data/studio/assets/index-B_j0pMD5.css +1 -0
- data/studio/assets/index-Ch4YEv9g.js +285 -0
- data/studio/index.html +27 -0
- data/studio/schema.yml +869 -0
- data/studio-app/README.md +27 -0
- data/studio-app/index.html +26 -0
- data/studio-app/package-lock.json +2499 -0
- data/studio-app/package.json +26 -0
- data/studio-app/skills-lock.json +47 -0
- data/studio-app/src/api/client.js +71 -0
- data/studio-app/src/editor/body-editor.js +70 -0
- data/studio-app/src/editor/liquid-core.js +382 -0
- data/studio-app/src/editor/liquid.js +77 -0
- data/studio-app/src/lib/document.js +207 -0
- data/studio-app/src/lib/list-controls.js +317 -0
- data/studio-app/src/lib/schema.js +66 -0
- data/studio-app/src/lib/yaml-doc.js +100 -0
- data/studio-app/src/main.js +3693 -0
- data/studio-app/src/media/browser.js +578 -0
- data/studio-app/src/preview/render.js +430 -0
- data/studio-app/src/styles/studio.css +2826 -0
- data/studio-app/vite.config.js +25 -0
- data/templates/articles/README.md +40 -0
- data/templates/articles/fixtures/article.md +9 -0
- data/templates/articles/screenshots/README.md +6 -0
- data/templates/articles/studio.yml +73 -0
- data/templates/articles/template.yml +21 -0
- data/templates/bibliography/README.md +41 -0
- data/templates/bibliography/fixtures/references.json +9 -0
- data/templates/bibliography/screenshots/README.md +6 -0
- data/templates/bibliography/studio.yml +66 -0
- data/templates/bibliography/template.yml +18 -0
- data/templates/blog/README.md +38 -0
- data/templates/blog/fixtures/post.md +9 -0
- data/templates/blog/screenshots/README.md +6 -0
- data/templates/blog/studio.yml +69 -0
- data/templates/blog/template.yml +20 -0
- data/templates/cv/README.md +34 -0
- data/templates/cv/fixtures/job.md +12 -0
- data/templates/cv/screenshots/README.md +6 -0
- data/templates/cv/studio.yml +200 -0
- data/templates/cv/template.yml +25 -0
- data/templates/media/README.md +38 -0
- data/templates/media/fixtures/resource.md +7 -0
- data/templates/media/screenshots/README.md +6 -0
- data/templates/media/studio.yml +58 -0
- data/templates/media/template.yml +17 -0
- data/templates/network/README.md +34 -0
- data/templates/network/fixtures/sources.json +3 -0
- data/templates/network/screenshots/README.md +6 -0
- data/templates/network/studio.yml +28 -0
- data/templates/network/template.yml +10 -0
- data/templates/portfolio/README.md +39 -0
- data/templates/portfolio/fixtures/project.md +10 -0
- data/templates/portfolio/screenshots/README.md +6 -0
- data/templates/portfolio/studio.yml +89 -0
- data/templates/portfolio/template.yml +18 -0
- metadata +505 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/* Ledger page styles: rascunhos. Owned by the rascunhos page; shared component rules
|
|
2
|
+
belong in assets/css/base.css under "Architectural Ledger blocks".
|
|
3
|
+
|
|
4
|
+
Every ledger sheet is linked on every page, so each selector here is scoped
|
|
5
|
+
to markup only this layout emits (.rascunhos-*) or to the blog page header
|
|
6
|
+
(.rascunhos-header). The sidebar is the exception by design: it is the same
|
|
7
|
+
.writing-rail block /pages/articles/ carries, styled once in writing.css and
|
|
8
|
+
placed here. Colour comes from the palette custom properties alone: a
|
|
9
|
+
literal hex would be correct in one theme and wrong in the other. */
|
|
10
|
+
|
|
11
|
+
/* The page is a bound notebook: entries ruled off from one another, each
|
|
12
|
+
opening on its number in the log, and months naming each run. Both devices
|
|
13
|
+
are computed from `date` and `last_updated`. Nothing on this page counts
|
|
14
|
+
words, times a read, names a city or numbers a volume. */
|
|
15
|
+
.rascunhos-main {
|
|
16
|
+
--rascunhos-plate: 6rem;
|
|
17
|
+
--rascunhos-rule: 1px solid var(--border-gentle-divider);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* ══ Masthead ══
|
|
21
|
+
The shard sits in this wrapper rather than in the shared page-header
|
|
22
|
+
include, which every listing renders and which no single page may restyle. */
|
|
23
|
+
.rascunhos-masthead {
|
|
24
|
+
position: relative;
|
|
25
|
+
margin-bottom: var(--space-2xl);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Sized to the masthead it accents. It used to be 24rem x 15rem, which fitted
|
|
29
|
+
while the filter deck was a strip under the title and made the masthead
|
|
30
|
+
260px tall; with the filter moved into the rail the masthead is 107px and a
|
|
31
|
+
15rem shard hung 50px into the body, cutting across the rail's keyword box.
|
|
32
|
+
An accent that reaches the content it is accenting is not an accent. */
|
|
33
|
+
.rascunhos-shard {
|
|
34
|
+
top: calc(-1 * var(--space-2xl));
|
|
35
|
+
right: calc(-1 * var(--space-xl));
|
|
36
|
+
width: 16rem;
|
|
37
|
+
height: 9rem;
|
|
38
|
+
/* Page accent (ochre via `.page-accent--ochre`), not the triad secondary. */
|
|
39
|
+
background: var(--color-primary);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Between the 640px shard cut-off and the desktop layout a 24rem shard is
|
|
43
|
+
wider than the masthead is tall: at 768px it covered the title and the
|
|
44
|
+
standfirst and read as a mis-clipped slab rather than a corner accent. The
|
|
45
|
+
writing lead and the CV dossier carry the same correction. */
|
|
46
|
+
@media (max-width: 1023px) {
|
|
47
|
+
.rascunhos-shard {
|
|
48
|
+
top: calc(-1 * var(--space-xl));
|
|
49
|
+
right: calc(-1 * var(--space-lg));
|
|
50
|
+
width: 12rem;
|
|
51
|
+
height: 8rem;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.rascunhos-header {
|
|
56
|
+
position: relative;
|
|
57
|
+
z-index: 1;
|
|
58
|
+
margin-bottom: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* ══ Body: ledger column beside the filter rail ══
|
|
62
|
+
Same split as /pages/articles/, to the rem: the sidebar is the same block
|
|
63
|
+
on both writing listings, so it takes the same column on both. Below 1024px
|
|
64
|
+
the rail is the shared disclosure and the grid collapses. */
|
|
65
|
+
.rascunhos-body {
|
|
66
|
+
display: block;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* `.hidden` swaps the listing for the detail view; it has to beat the grid. */
|
|
70
|
+
.rascunhos-body.hidden {
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@media (min-width: 1024px) {
|
|
75
|
+
.rascunhos-body {
|
|
76
|
+
display: grid;
|
|
77
|
+
grid-template-columns: minmax(0, 1fr) 16rem;
|
|
78
|
+
gap: var(--space-2xl);
|
|
79
|
+
align-items: start;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.rascunhos-ledger {
|
|
83
|
+
grid-column: 1;
|
|
84
|
+
grid-row: 1;
|
|
85
|
+
min-width: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.rascunhos-body > .writing-rail {
|
|
89
|
+
grid-column: 2;
|
|
90
|
+
grid-row: 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media (min-width: 1280px) {
|
|
95
|
+
.rascunhos-body {
|
|
96
|
+
grid-template-columns: minmax(0, 1fr) 18rem;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* A legend, not notation. The mono face came off legends and dates site-wide;
|
|
101
|
+
this is the same treatment `.ledger-kicker` carries in base.css. */
|
|
102
|
+
.rascunhos-ledger-head {
|
|
103
|
+
display: flex;
|
|
104
|
+
flex-wrap: wrap;
|
|
105
|
+
align-items: baseline;
|
|
106
|
+
justify-content: space-between;
|
|
107
|
+
gap: var(--space-sm);
|
|
108
|
+
padding-bottom: var(--space-sm);
|
|
109
|
+
margin-bottom: var(--space-lg);
|
|
110
|
+
color: var(--color-on-surface-variant);
|
|
111
|
+
font-family: var(--font-body);
|
|
112
|
+
font-size: var(--type-meta);
|
|
113
|
+
font-weight: var(--weight-label);
|
|
114
|
+
text-transform: uppercase;
|
|
115
|
+
letter-spacing: 0.06em;
|
|
116
|
+
border-bottom: 1px solid var(--border-gentle-divider);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* No gap: each entry is closed by the hairline under it, so the rows have to
|
|
120
|
+
touch or the ruling dashes itself between them. */
|
|
121
|
+
.rascunhos-entries {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
gap: var(--space-md);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.rascunhos-state {
|
|
128
|
+
padding: var(--space-xl);
|
|
129
|
+
background: var(--color-surface-card);
|
|
130
|
+
border: 1.5px solid var(--border-ink);
|
|
131
|
+
border-radius: var(--radius-card);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* ══ The page ══
|
|
135
|
+
Every child of the ledger — entry, month heading — is the same band, so the
|
|
136
|
+
run of entries keeps one rhythm wherever a heading interrupts it.
|
|
137
|
+
|
|
138
|
+
The band used to be two columns, with a ruled margin on the left holding the
|
|
139
|
+
folio number and the revision note. Both are facts about the entry, so both
|
|
140
|
+
now sit in the entry's own ledger line, and a ruled column holding nothing
|
|
141
|
+
is a rule drawn for its own sake. */
|
|
142
|
+
.rascunhos-band {
|
|
143
|
+
display: block;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* The hover fill is painted on the whole band, so whatever sits hard against
|
|
147
|
+
the body's right edge ends up with the fill's edge drawn along its own
|
|
148
|
+
border. That is what the classification chip was doing: two rectangles
|
|
149
|
+
sharing an edge, reading as one mis-drawn box. The body keeps a gutter on
|
|
150
|
+
both sides and nothing touches the fill. */
|
|
151
|
+
.rascunhos-band-body {
|
|
152
|
+
/* Named because the plate cancels exactly this padding to reach the rules
|
|
153
|
+
above and below it; a literal in both places would drift at the first
|
|
154
|
+
breakpoint that changes one of them. */
|
|
155
|
+
--rascunhos-body-pad-top: var(--space-lg);
|
|
156
|
+
--rascunhos-body-pad-bottom: var(--space-lg);
|
|
157
|
+
min-width: 0;
|
|
158
|
+
padding: var(--rascunhos-body-pad-top) var(--space-lg) var(--rascunhos-body-pad-bottom);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* The folio: the entry's place in the log, assigned once over the whole corpus
|
|
162
|
+
so a filter cannot renumber it. A figure, which is the remaining case for
|
|
163
|
+
monospace on this site — and a run of them down the ledger only lines up
|
|
164
|
+
because the face is monospaced. It opens the line, so it takes the weight
|
|
165
|
+
the rest of the strip does not. */
|
|
166
|
+
.rascunhos-folio {
|
|
167
|
+
color: var(--color-on-surface);
|
|
168
|
+
font-size: var(--type-meta);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* The quieter half of the ledger line: it explains why an entry is where the
|
|
172
|
+
revision sort puts it without competing with the date it was written. Twin
|
|
173
|
+
of `.writing-revised` on the articles archive. */
|
|
174
|
+
.rascunhos-revision {
|
|
175
|
+
color: color-mix(in srgb, var(--color-on-surface-variant) 78%, transparent);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* ══ Rhythm: the month opening each run ══
|
|
179
|
+
Not small caps and not mono — it is a legend. The space above it is what
|
|
180
|
+
makes a month of six entries look different from a month of one. */
|
|
181
|
+
.rascunhos-month > .rascunhos-band-body {
|
|
182
|
+
padding-top: var(--space-2xl);
|
|
183
|
+
padding-bottom: var(--space-xs);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.rascunhos-month-label {
|
|
187
|
+
margin: 0;
|
|
188
|
+
color: var(--color-on-surface-variant);
|
|
189
|
+
font-family: var(--font-body);
|
|
190
|
+
font-size: var(--type-meta);
|
|
191
|
+
font-weight: var(--weight-emphasis);
|
|
192
|
+
letter-spacing: 0.05em;
|
|
193
|
+
text-transform: uppercase;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* Entry titles — a step above the shared ledger-row scale so the notebook
|
|
197
|
+
line reads as a title, not a caption. */
|
|
198
|
+
.rascunhos-row .ledger-row-title {
|
|
199
|
+
font-size: var(--type-card-lg);
|
|
200
|
+
line-height: 1.25;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* ══ Ledger entry ══
|
|
204
|
+
Ruled paper, not a stack of cards: the shared row's card fill and padding
|
|
205
|
+
come off, and what separates two entries is the hairline under each one.
|
|
206
|
+
The fill returns on hover, which is the only moment a row needs to be an
|
|
207
|
+
object rather than a line on a page. */
|
|
208
|
+
.ledger-row.rascunhos-row {
|
|
209
|
+
gap: 0;
|
|
210
|
+
padding: 0;
|
|
211
|
+
background: var(--color-surface-card);
|
|
212
|
+
border: 1.5px solid var(--border-ink);
|
|
213
|
+
border-radius: var(--radius-card);
|
|
214
|
+
transition: background-color var(--motion-duration-fast) var(--motion-ease-default),
|
|
215
|
+
border-color var(--motion-duration-fast) var(--motion-ease-default);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.ledger-row.rascunhos-row:hover {
|
|
219
|
+
background: var(--color-surface-high);
|
|
220
|
+
border-color: var(--color-primary);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.ledger-row.rascunhos-row:hover .ledger-row-title a {
|
|
224
|
+
color: var(--color-primary);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.rascunhos-row > .rascunhos-band-body {
|
|
228
|
+
display: flex;
|
|
229
|
+
flex-direction: column;
|
|
230
|
+
gap: var(--space-sm);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.rascunhos-row .ledger-row-head {
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-wrap: wrap;
|
|
236
|
+
align-items: center;
|
|
237
|
+
justify-content: space-between;
|
|
238
|
+
gap: var(--space-sm);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* Date and language sit left, classification right, as in the mockup. */
|
|
242
|
+
.rascunhos-row .ledger-row-head .ledger-meta {
|
|
243
|
+
margin-right: auto;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.rascunhos-row .ledger-row-copy {
|
|
247
|
+
max-width: var(--reading-measure, 45rem);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* The row carries no read-more link — the title is the link. The mockup's
|
|
251
|
+
hover arrow is not reproduced: as an inline pseudo-element it reserves a
|
|
252
|
+
character of line width even while invisible, which tips a title that fits
|
|
253
|
+
on one line onto two. The shared row already answers the hover with a
|
|
254
|
+
surface step and a colour change on the title.
|
|
255
|
+
|
|
256
|
+
The focus ring used to be the secondary at 45%, which washed out to 1.92:1
|
|
257
|
+
against the card in light and 2.54:1 in dark — below the 3:1 a focus
|
|
258
|
+
indicator owes, and weaker than the browser ring it was replacing.
|
|
259
|
+
Full-strength primary is 6.67:1 and 8.10:1 on the same two surfaces. */
|
|
260
|
+
.rascunhos-row .ledger-row-title a:focus-visible {
|
|
261
|
+
outline: 2px solid var(--color-primary);
|
|
262
|
+
outline-offset: 3px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* Thumbnails are set on almost every exported post, so the entry carries a
|
|
266
|
+
small plate to scan by. The body only becomes two columns once an image is
|
|
267
|
+
actually in it — a post without one, or whose remote image 404s, keeps the
|
|
268
|
+
plain stacked entry rather than an indent against an empty gutter. */
|
|
269
|
+
.rascunhos-row--illustrated > .rascunhos-band-body {
|
|
270
|
+
display: grid;
|
|
271
|
+
/* Three explicit rows — meta, title, preview — so the plate's `1 / -1`
|
|
272
|
+
resolves against a real explicit grid instead of collapsing to row 1 and
|
|
273
|
+
pushing the title down by the height of the image. */
|
|
274
|
+
grid-template-columns: var(--rascunhos-plate) minmax(0, 1fr);
|
|
275
|
+
grid-template-rows: auto auto auto;
|
|
276
|
+
column-gap: var(--space-lg);
|
|
277
|
+
row-gap: var(--space-sm);
|
|
278
|
+
align-items: start;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* The plate is a column of the entry, not a stamp in its corner: it spans
|
|
282
|
+
every row of the body and stretches to the height they come out at, so an
|
|
283
|
+
entry with three lines of preview and an entry with one are both fully
|
|
284
|
+
faced. The negative block margin cancels the body's own padding, which puts
|
|
285
|
+
the top and bottom of the image on the rules that bound the entry — the
|
|
286
|
+
plate covers the card, rather than floating inside it. */
|
|
287
|
+
.rascunhos-row--illustrated .rascunhos-row-media {
|
|
288
|
+
grid-column: 1;
|
|
289
|
+
grid-row: 1 / -1;
|
|
290
|
+
align-self: stretch;
|
|
291
|
+
margin-block: calc(-1 * var(--rascunhos-body-pad-top))
|
|
292
|
+
calc(-1 * var(--rascunhos-body-pad-bottom));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.rascunhos-row--illustrated > .rascunhos-band-body > :not(.rascunhos-row-media) {
|
|
296
|
+
grid-column: 2;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* No aspect ratio: the height is whatever the entry beside it works out to,
|
|
300
|
+
and `object-fit: cover` below crops to it. A fixed ratio here would fight
|
|
301
|
+
the stretch and reintroduce the fixed plate. */
|
|
302
|
+
.rascunhos-row-media {
|
|
303
|
+
width: var(--rascunhos-plate);
|
|
304
|
+
overflow: hidden;
|
|
305
|
+
background: var(--color-surface-container);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* Grain. These are pasted-in crops, not hero images: held back far enough
|
|
309
|
+
that a column of them reads as texture beside the writing, and coming up to
|
|
310
|
+
full colour only for the entry under the cursor. */
|
|
311
|
+
.rascunhos-row-media img {
|
|
312
|
+
display: block;
|
|
313
|
+
width: 100%;
|
|
314
|
+
height: 100%;
|
|
315
|
+
object-fit: cover;
|
|
316
|
+
filter: grayscale(0.55) contrast(1.03);
|
|
317
|
+
transition: filter var(--motion-duration-base) var(--motion-ease-default);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.rascunhos-row:hover .rascunhos-row-media img,
|
|
321
|
+
.rascunhos-row:focus-within .rascunhos-row-media img {
|
|
322
|
+
filter: grayscale(0) contrast(1);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
@media (prefers-reduced-motion: reduce) {
|
|
326
|
+
.rascunhos-row-media img {
|
|
327
|
+
transition: none;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* A phone spends its width on the sentence. The entry keeps its gutters but
|
|
332
|
+
loses most of the block padding. */
|
|
333
|
+
@media (max-width: 767px) {
|
|
334
|
+
.rascunhos-band-body {
|
|
335
|
+
--rascunhos-body-pad-top: var(--space-sm);
|
|
336
|
+
padding-inline: var(--space-md);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* Below the tablet breakpoint the plate goes, and the entry becomes pure
|
|
341
|
+
typography — the same call the home page's draft ledger makes, for the same
|
|
342
|
+
reason. Even at 4rem the plate left the excerpt about 23 characters a line
|
|
343
|
+
at 390px, which is not a measure, and it reserved a column of empty gutter
|
|
344
|
+
down the rest of the row. A thumbnail is decoration on a text ledger; the
|
|
345
|
+
sentence is not. */
|
|
346
|
+
@media (max-width: 639px) {
|
|
347
|
+
.rascunhos-row--illustrated > .rascunhos-band-body {
|
|
348
|
+
display: flex;
|
|
349
|
+
flex-direction: column;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.rascunhos-row--illustrated .rascunhos-row-media {
|
|
353
|
+
display: none;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* ══ Pagination ══
|
|
358
|
+
The buttons are `.pagination-nav-btn` from base.css, shared with the writing
|
|
359
|
+
index and sources; only the bar around them is local. */
|
|
360
|
+
.rascunhos-pagination {
|
|
361
|
+
display: flex;
|
|
362
|
+
align-items: center;
|
|
363
|
+
justify-content: center;
|
|
364
|
+
gap: var(--space-lg);
|
|
365
|
+
margin-top: var(--space-lg);
|
|
366
|
+
padding: var(--space-sm) var(--space-md);
|
|
367
|
+
background: var(--color-panel-contrast);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.rascunhos-pagination.hidden {
|
|
371
|
+
display: none;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* Pagination count face/size live on `.pagination-count` in base.css.
|
|
375
|
+
Keep nowrap so "4 / 4" does not stack between the buttons at 390px. */
|
|
376
|
+
.rascunhos-pagination > span {
|
|
377
|
+
white-space: nowrap;
|
|
378
|
+
}
|
|
379
|
+
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/* Ledger page styles: sources. Owned by the sources page; shared component rules
|
|
2
|
+
belong in assets/css/base.css under "Architectural Ledger blocks".
|
|
3
|
+
|
|
4
|
+
The sources grid is the archive card from 43-blocks.html with three additions
|
|
5
|
+
the resources collection earns and no other listing has: a poster from
|
|
6
|
+
`thumbnail`, a row of four facet chips read off `type`, `category` and
|
|
7
|
+
`language`, and the publisher host from `link`. Every colour is a token, so
|
|
8
|
+
both palettes resolve from the same rules. */
|
|
9
|
+
|
|
10
|
+
/* ── Shards ──
|
|
11
|
+
The page had no depth treatment of any kind, and it is the wrong shape for
|
|
12
|
+
the ambient pool the home bands carry: a pool beNewsreader a grid of many small
|
|
13
|
+
cards only darkens one corner of it. Shards instead, the two canonical
|
|
14
|
+
polygons from base.css, one at each end of the run — top right above the
|
|
15
|
+
grid, bottom left below it, the diagonal pair the CV dossier uses inside
|
|
16
|
+
one panel, opened out across the page. In dark the source cards stay
|
|
17
|
+
opaque so the shard reads in the gutter, not through the poster.
|
|
18
|
+
|
|
19
|
+
Neither container takes `overflow: hidden`: the masthead holds the filter
|
|
20
|
+
popover, which would be clipped by it. The offsets are therefore sized to
|
|
21
|
+
stay inside the page's own gutter at every width the shards survive, the
|
|
22
|
+
way the rascunhos masthead does it. The shared utility already unmounts
|
|
23
|
+
both below 640px. */
|
|
24
|
+
/* The masthead outranks the grid because the filter popover opens out of it.
|
|
25
|
+
Lifting the header over its own shard puts the popover inside a stacking
|
|
26
|
+
context, and the grid below has to be lifted over the foot shard in the
|
|
27
|
+
same way — without this the cards would be painted over an open filter
|
|
28
|
+
panel. */
|
|
29
|
+
.sources-masthead {
|
|
30
|
+
position: relative;
|
|
31
|
+
z-index: 2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
.sources-header {
|
|
37
|
+
position: relative;
|
|
38
|
+
z-index: 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sources-header .page-header-tags {
|
|
42
|
+
color: var(--color-primary);
|
|
43
|
+
opacity: 0.85;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sources-masthead-shard {
|
|
47
|
+
top: calc(-1 * var(--space-2xl));
|
|
48
|
+
right: calc(-1 * var(--space-xl));
|
|
49
|
+
width: 16rem;
|
|
50
|
+
height: 9rem;
|
|
51
|
+
background: var(--color-primary);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.sources-body {
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* A card is not positioned, so without this the shard — which is — would be
|
|
59
|
+
painted over the bottom row rather than beNewsreader it. The rule the whole
|
|
60
|
+
family answers to is that a backdrop never touches the object in front of
|
|
61
|
+
it. */
|
|
62
|
+
.sources-body>.listing-card-grid,
|
|
63
|
+
.sources-body>.source-pagination {
|
|
64
|
+
position: relative;
|
|
65
|
+
z-index: 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* The foot of the page, beside the pagination. It reaches up beNewsreader the last
|
|
69
|
+
row of cards. In dark those cards are opaque again, so what shows is the
|
|
70
|
+
wedge in the gutter and the band across the pagination strip. */
|
|
71
|
+
.sources-foot-shard {
|
|
72
|
+
left: calc(-1 * var(--space-xl));
|
|
73
|
+
bottom: calc(-1 * var(--space-lg));
|
|
74
|
+
width: 14rem;
|
|
75
|
+
height: 8rem;
|
|
76
|
+
background: color-mix(in srgb, var(--color-primary) 70%, transparent);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Below the desktop layout the page gutter halves, so the shards have to come
|
|
80
|
+
back inside it or they widen the document. */
|
|
81
|
+
@media (max-width: 1023px) {
|
|
82
|
+
.sources-masthead-shard {
|
|
83
|
+
top: calc(-1 * var(--space-xl));
|
|
84
|
+
right: calc(-1 * var(--space-lg));
|
|
85
|
+
width: 12rem;
|
|
86
|
+
height: 8rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.sources-foot-shard {
|
|
90
|
+
left: calc(-1 * var(--space-lg));
|
|
91
|
+
width: 10rem;
|
|
92
|
+
height: 7rem;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Pagination hides rather than unmounts, so the cards keep their identity
|
|
97
|
+
between pages and the filter only has to toggle a class. */
|
|
98
|
+
.resource-hidden {
|
|
99
|
+
display: none !important;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Three across at desktop rather than four: a card now carries a poster, a
|
|
103
|
+
summary and a footer, and a quarter of the row is too narrow for that. */
|
|
104
|
+
.listing-card-grid--sources {
|
|
105
|
+
--listing-grid-cols: 2;
|
|
106
|
+
gap: var(--space-lg);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@media (min-width: 1024px) {
|
|
110
|
+
.listing-card-grid--sources {
|
|
111
|
+
--listing-grid-cols: 3;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@media (min-width: 1280px) {
|
|
116
|
+
.listing-card-grid--sources {
|
|
117
|
+
--listing-grid-cols: 3;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ── The source card ── */
|
|
122
|
+
|
|
123
|
+
/* The poster is full-bleed: it sits outside .ledger-card-body, so the card's
|
|
124
|
+
own padding never boxes it in. A single hairline separates it from the text
|
|
125
|
+
block, which is the only depth cue the surface ladder allows. Thumbnails
|
|
126
|
+
arrive from other people's sites at wildly different crops, so the card
|
|
127
|
+
imposes one ratio and lets the fill do the rest.
|
|
128
|
+
|
|
129
|
+
That ratio is the video frame, 16:9 — the native size of the YouTube
|
|
130
|
+
thumbnails most of this collection links to (maxresdefault is 1280x720,
|
|
131
|
+
hq720 likewise). At 16:10 the fill cropped a slice off the top and bottom
|
|
132
|
+
of every one of them; at 16:9 they land whole. The card keeps the width
|
|
133
|
+
the grid gives it, so the change lands in the height. */
|
|
134
|
+
.source-card>.ledger-poster {
|
|
135
|
+
aspect-ratio: 16 / 9;
|
|
136
|
+
border-bottom: 1px solid var(--border-gentle-subtle);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.source-card-title {
|
|
140
|
+
overflow-wrap: anywhere;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ── The facet row ──
|
|
144
|
+
|
|
145
|
+
A source declares four things about itself — medium, category, language,
|
|
146
|
+
country — and the card used to scatter them: two in the meta line above the
|
|
147
|
+
title, one in a chip row below the description, and the country nowhere at
|
|
148
|
+
all, even though every locale in the collection names one. They are one
|
|
149
|
+
fact about the source, so they are now one row of four chips.
|
|
150
|
+
|
|
151
|
+
The row is a single family: same height, same type, same hairline, each
|
|
152
|
+
carrying its own ink. Height is fixed rather than intrinsic, because the
|
|
153
|
+
chips do not all hold text — the country chip holds an image, and matching
|
|
154
|
+
heights by padding alone would leave it a pixel or two short of the rest.
|
|
155
|
+
Chips never wrap internally; the row wraps instead, so a narrow card breaks
|
|
156
|
+
between chips and not through one. */
|
|
157
|
+
.source-facets {
|
|
158
|
+
--source-facet-height: 1.65rem;
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-wrap: wrap;
|
|
161
|
+
align-items: center;
|
|
162
|
+
gap: var(--space-xs);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* The category chip comes from the shared renderer, which wraps its output in
|
|
166
|
+
a .ledger-chip-row. `display: contents` dissolves that wrapper so the chip
|
|
167
|
+
joins this row as a sibling of the other three, rather than sitting in a
|
|
168
|
+
nested flex box that would set its own height. The shared renderer is left
|
|
169
|
+
exactly as it is. */
|
|
170
|
+
.source-facets .ledger-chip-row {
|
|
171
|
+
display: contents;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* One geometry for all four. The border is currentColor rather than a fixed
|
|
175
|
+
token, so each chip outlines itself in whatever ink it is already using and
|
|
176
|
+
the row stays a family across both palettes. The shared category chip is a
|
|
177
|
+
filled chip everywhere else on the site; here it outlines like its three
|
|
178
|
+
neighbors, and its hover still fills — which is how a reader can tell that
|
|
179
|
+
this one, alone, is a link. */
|
|
180
|
+
.source-facets .source-facet,
|
|
181
|
+
.source-facets .ledger-chip,
|
|
182
|
+
.source-facets .lang-pill {
|
|
183
|
+
display: inline-flex;
|
|
184
|
+
align-items: center;
|
|
185
|
+
height: var(--source-facet-height);
|
|
186
|
+
padding: 0 var(--space-sm);
|
|
187
|
+
border: 1.5px solid color-mix(in srgb, currentColor 40%, var(--border-ink));
|
|
188
|
+
border-radius: var(--radius-card);
|
|
189
|
+
background: transparent;
|
|
190
|
+
white-space: nowrap;
|
|
191
|
+
font-size: var(--type-label);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* The two chips this page owns. The shared pill and chip bring their own
|
|
195
|
+
type; these match it rather than inventing a second label voice. */
|
|
196
|
+
.source-facet {
|
|
197
|
+
font-family: var(--font-label);
|
|
198
|
+
font-size: var(--type-label);
|
|
199
|
+
font-weight: var(--weight-label);
|
|
200
|
+
letter-spacing: 0.03em;
|
|
201
|
+
line-height: 1;
|
|
202
|
+
color: var(--color-on-surface-variant);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* flag-icons sizes from the em, so the flag's own font-size is its height. */
|
|
206
|
+
.source-facet--country {
|
|
207
|
+
padding-inline: 0.35rem;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.source-facet--country .fi {
|
|
211
|
+
font-size: var(--type-dek);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* The publisher, sitting opposite the call to action on the footer rule. */
|
|
215
|
+
.source-host {
|
|
216
|
+
color: var(--color-on-surface-variant);
|
|
217
|
+
text-transform: lowercase;
|
|
218
|
+
letter-spacing: 0.02em;
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
text-overflow: ellipsis;
|
|
221
|
+
white-space: nowrap;
|
|
222
|
+
min-width: 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Filter swatches: match the exact medium accent colours used by cards
|
|
226
|
+
(--color-res-youtube for red, --color-res-podcast for green,
|
|
227
|
+
--color-res-doc for amber/brown, --color-primary for website blue). */
|
|
228
|
+
.source-swatch--youtube {
|
|
229
|
+
background: var(--color-res-youtube);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.source-swatch--podcast {
|
|
233
|
+
background: var(--color-res-podcast);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.source-swatch--document {
|
|
237
|
+
background: var(--color-res-doc);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.source-swatch--website {
|
|
241
|
+
background: var(--color-primary);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* ── Pagination ── */
|
|
245
|
+
|
|
246
|
+
/* Real UI over a real index, not a registry counter: the page reads how many
|
|
247
|
+
pages the current filter produced, and nothing else. The buttons themselves
|
|
248
|
+
are `.pagination-nav-btn` from base.css, shared with the other two
|
|
249
|
+
listings; only the bar around them is local. */
|
|
250
|
+
.source-pagination {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
gap: var(--space-lg);
|
|
255
|
+
margin-top: var(--space-2xl);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.source-pagination:empty {
|
|
259
|
+
margin-top: 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* ── Medium colour ──
|
|
263
|
+
A source is recognised by what it is before it is read — a video, a
|
|
264
|
+
podcast, a site — and the palette already carries a colour per medium
|
|
265
|
+
(--color-res-*). The redesign had flattened all four onto the brand triad,
|
|
266
|
+
which cost the fastest signal on the page. The colour drives the medium
|
|
267
|
+
chip and an edge on the card, so it reads at a glance without turning the
|
|
268
|
+
grid into a set of logos. */
|
|
269
|
+
|
|
270
|
+
.source-card {
|
|
271
|
+
--source-accent: var(--color-tertiary);
|
|
272
|
+
border-left: 3px solid var(--source-accent);
|
|
273
|
+
background: var(--color-surface-card);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.source-card-media {
|
|
277
|
+
position: relative;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.source-card-media .ledger-frame-corners {
|
|
281
|
+
--frame-corner-size: 0.7rem;
|
|
282
|
+
inset: 0.3rem;
|
|
283
|
+
z-index: 2;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Align Sources posters with the Articles/detail plate dialect. */
|
|
287
|
+
.source-card .ledger-poster {
|
|
288
|
+
border-bottom: 1px solid color-mix(in srgb, var(--source-accent) 40%, transparent);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* Light paper densifies every `.ledger-card` border to `--border-ink-strong`
|
|
292
|
+
(base.css). That `border-color` rewrite also paints the left edge and
|
|
293
|
+
erases the medium accent — pin the left colour back after the light bump. */
|
|
294
|
+
:root:not([data-theme="dark"]) .source-card,
|
|
295
|
+
html[data-theme="light"] .source-card {
|
|
296
|
+
border-left-color: var(--source-accent);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* Transparent resting cards work on the home and writing grids; on Sources
|
|
300
|
+
the poster + facet chip stack needs a solid plate in dark so the shard and
|
|
301
|
+
canvas do not read through the thumbnail. Restore the pre-transparent
|
|
302
|
+
ladder card (#1a1a1e). Light keeps the shared transparent rest. */
|
|
303
|
+
[data-theme="dark"] .source-card {
|
|
304
|
+
background: #1a1a1e;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.source-card[data-medium="youtube"] {
|
|
308
|
+
--source-accent: var(--color-res-youtube);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.source-card[data-medium="podcast"] {
|
|
312
|
+
--source-accent: var(--color-res-podcast);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.source-card[data-medium="document"] {
|
|
316
|
+
--source-accent: var(--color-res-doc);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.source-card[data-medium="website"] {
|
|
320
|
+
--source-accent: var(--color-primary);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* The medium chip and the card edge read the same custom property, so they
|
|
324
|
+
cannot drift apart: one colour, stated once, shown twice. */
|
|
325
|
+
.source-facet--medium {
|
|
326
|
+
color: var(--source-accent);
|
|
327
|
+
}
|