feat(themes): set generic css variables for colors to enable instance themes

- set new colors using the css variables for theming in tailwind.config.js
- replace admin and
public colors with new variable enabled colors
This commit is contained in:
Yassine Doghri 2021-11-05 14:36:34 +00:00
parent f611a16cd0
commit a746a781b4
118 changed files with 701 additions and 557 deletions

View File

@ -119,7 +119,7 @@ class EpisodeComment extends UuidEntity
public function getHasReplies(): bool
{
return $this->getReplies() !== null;
return $this->getReplies() !== [];
}
public function getReplyToComment(): ?self

View File

@ -24,9 +24,9 @@ if (! function_exists('hint_tooltip')) {
function hint_tooltip(string $hintText = '', string $class = ''): string
{
$tooltip =
'<span data-toggle="tooltip" data-placement="bottom" tabindex="0" title="' .
'<span data-tooltip="bottom" tabindex="0" title="' .
$hintText .
'" class="inline-block text-gray-500 align-middle focus:ring-castopod';
'" class="inline-block align-middle text-skin-muted focus:ring-accent';
if ($class !== '') {
$tooltip .= ' ' . $class;
@ -56,14 +56,14 @@ if (! function_exists('data_table')) {
'table_open' => '<table class="w-full whitespace-no-wrap">',
'thead_open' =>
'<thead class="text-xs font-semibold text-left text-gray-500 uppercase">',
'<thead class="text-xs font-semibold text-left uppercase text-skin-muted">',
'heading_cell_start' => '<th class="px-4 py-2">',
'cell_start' => '<td class="px-4 py-2">',
'cell_alt_start' => '<td class="px-4 py-2">',
'row_start' => '<tr class="border-t hover:bg-pine-50">',
'row_alt_start' => '<tr class="border-t hover:bg-pine-50">',
'row_start' => '<tr class="border-t border-subtle hover:bg-base">',
'row_alt_start' => '<tr class="border-t border-subtle hover:bg-base">',
];
$table->setTemplate($template);
@ -88,7 +88,7 @@ if (! function_exists('data_table')) {
return lang('Common.no_data');
}
return '<div class="overflow-x-auto bg-white rounded-lg border-3 border-pine-100 ' . $class . '" >' .
return '<div class="overflow-x-auto rounded-lg bg-elevated border-3 border-subtle ' . $class . '" >' .
$table->generate() .
'</div>';
}
@ -105,7 +105,7 @@ if (! function_exists('publication_pill')) {
function publication_pill(?Time $publicationDate, string $publicationStatus, string $customClass = ''): string
{
$class = match ($publicationStatus) {
'published' => 'text-pine-600 border-pine-600 bg-pine-50',
'published' => 'text-pine-500 border-pine-500 bg-pine-50',
'scheduled' => 'text-red-600 border-red-600 bg-red-50',
'not_published' => 'text-gray-600 border-gray-600 bg-gray-50',
default => 'text-gray-600 border-gray-600 bg-gray-50',
@ -208,7 +208,7 @@ if (! function_exists('episode_numbering')) {
$class .
'" title="' .
lang($transKey, $args) .
'">' .
'" data-tooltip="bottom">' .
lang($transKey . '_abbr', $args) .
'</abbr>';
}
@ -238,7 +238,7 @@ if (! function_exists('location_link')) {
icon('map-pin', 'mr-2') . $location->name,
[
'class' =>
'inline-flex items-baseline hover:underline focus:ring-castopod' .
'inline-flex items-baseline hover:underline focus:ring-accent' .
($class === '' ? '' : " {$class}"),
'target' => '_blank',
'rel' => 'noreferrer noopener',
@ -264,8 +264,8 @@ if (! function_exists('audio_player')) {
theme="light"
language="{$language}"
icons="castopod-icons"
class="{$class}"
style="--vm-player-box-shadow:0; --vm-player-theme: #009486; --vm-control-spacing: 4px;"
class="{$class} relative z-0"
style="--vm-player-box-shadow:0; --vm-player-theme: hsl(var(--color-accent-base)); --vm-control-focus-color: hsl(var(--color-accent-contrast)); --vm-control-spacing: 4px; --vm-menu-item-focus-bg: hsl(var(--color-background-highlight));"
>
<vm-audio preload="none">
<source src="{$source}" type="{$mediaType}" />

View File

@ -20,17 +20,17 @@ if (! function_exists('render_page_links')) {
{
$pages = (new PageModel())->findAll();
$links = anchor(route_to('home'), lang('Common.home'), [
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-castopod',
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
]);
$links .= anchor(route_to('credits'), lang('Person.credits'), [
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-castopod',
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
]);
$links .= anchor(route_to('map'), lang('Page.map'), [
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-castopod',
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
]);
foreach ($pages as $page) {
$links .= anchor($page->link, $page->title, [
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-castopod',
'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
]);
}

View File

@ -39,14 +39,18 @@ import "./modules/play-episode-button";
const player = html`<div
id="castopod-audio-player"
class="fixed bottom-0 left-0 flex flex-col w-full bg-white border-t sm:flex-row z-50"
class="fixed bottom-0 left-0 flex flex-col w-full bg-elevated border-t border-subtle sm:flex-row z-50"
data-episode="-1"
style="display: none;"
>
<div class="flex items-center">
<img src="" alt="" class="h-[52px] w-[52px]" />
<div class="flex flex-col px-2">
<p class="text-sm w-48 truncate" title="" id="castopod-player-title"></p>
<p
class="text-sm w-48 truncate font-semibold"
title=""
id="castopod-player-title"
></p>
<p
class="text-xs w-48 truncate"
title=""
@ -60,7 +64,7 @@ const player = html`<div
language="en"
icons="castopod-icons"
class="flex-1"
style="--vm-player-box-shadow:0; --vm-player-theme: #009486;"
style="--vm-player-box-shadow:0; --vm-player-theme: hsl(var(--color-accent-base)); --vm-control-focus-color: hsl(var(--color-accent-contrast)); --vm-menu-item-focus-bg: hsl(var(--color-background-highlight));"
>
<vm-audio preload="none" id="testing-audio">
<source src="" type="" />

View File

@ -46,13 +46,13 @@ const drawEpisodesMap = async (mapDivId: string, dataUrl: string) => {
data[i].latitude,
data[i].longitude,
]).bindPopup(
'<div class="flex min-w-max"><img src="' +
'<div class="flex min-w-max w-full gap-x-2"><img src="' +
data[i].cover_path +
'" alt="' +
data[i].episode_title +
'" class="mr-2 rounded w-16 h-16" /><div class="flex flex-col"><h2 class="lg:text-base text-sm ! font-bold"><a href="' +
'" class="rounded w-16 h-16" /><div class="flex flex-col flex-1"><h2 class="leading-tight text-sm w-56 line-clamp-2 font-bold"><a href="' +
data[i].episode_link +
'" class="hover:underline !text-pine-800">' +
'" class="hover:underline font-semibold !text-accent-base">' +
data[i].episode_title +
'</a></h2><a href="' +
data[i].podcast_link +

View File

@ -1,9 +1,8 @@
import { createPopper, Placement } from "@popperjs/core";
const Tooltip = (): void => {
const tooltipContainers: NodeListOf<HTMLElement> = document.querySelectorAll(
"[data-toggle='tooltip']"
);
const tooltipContainers: NodeListOf<HTMLElement> =
document.querySelectorAll("[data-tooltip]");
for (let i = 0; i < tooltipContainers.length; i++) {
const tooltipReference = tooltipContainers[i];
@ -18,7 +17,7 @@ const Tooltip = (): void => {
tooltip.innerHTML = tooltipContent;
const popper = createPopper(tooltipReference, tooltip, {
placement: tooltipReference.dataset.placement as Placement,
placement: tooltipReference.dataset.tooltip as Placement,
modifiers: [
{
name: "offset",

View File

@ -1,5 +1,5 @@
import MarkdownToolbarElement from "@github/markdown-toolbar-element";
import { html, LitElement, TemplateResult } from "lit";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import marked from "marked";
@ -52,9 +52,21 @@ export class MarkdownPreview extends LitElement {
});
}
static styles = css`
* {
max-width: 65ch;
}
a {
font-weight: 600;
color: hsl(var(--color-accent-base));
text-decoration: none;
}
`;
render(): TemplateResult<1> {
return html`${this._show
? html`${unsafeHTML(this.markdownToHtml())}`
? html`${unsafeHTML(this.markdownToHtml())}</div>`
: html``}`;
}
}

View File

@ -63,7 +63,7 @@ export class MarkdownWritePreview extends LitElement {
width: 80%;
height: 4px;
margin: 0 auto;
background-color: #009486;
background-color: hsl(var(--color-accent-base));
border-radius: 9999px;
}
`;

View File

@ -156,6 +156,7 @@ export class PermalinkEdit extends LitElement {
button svg,
clipboard-copy svg {
fill: hsl(var(--color-text-base));
opacity: 0.6;
font-size: 1.25rem;
}

View File

@ -189,7 +189,7 @@ export class PlayEpisodeButton extends LitElement {
static styles = css`
button {
background-color: #009486;
background-color: hsl(var(--color-accent-base));
cursor: pointer;
display: inline-flex;
align-items: center;
@ -203,30 +203,31 @@ export class PlayEpisodeButton extends LitElement {
}
button:hover {
background-color: #00564a;
background-color: hsl(var(--color-accent-hover));
}
button:focus {
outline: none;
box-shadow: 0 0 0 2px #e7f9e4, 0 0 0 4px #009486;
box-shadow: 0 0 0 2px hsl(var(--color-background-base)),
0 0 0 4px hsl(var(--color-accent-base));
}
button.playing {
background-color: #f2faf9;
border: 2px solid #009486;
background-color: hsl(var(--color-background-base));
border: 2px solid hsl(var(--color-accent-base));
}
button.playing:hover {
background-color: #e7f9e4;
background-color: hsl(var(--color-background-elevated));
}
button.playing svg {
color: #009486;
color: hsl(var(--color-accent-base));
}
svg {
font-size: 1.5rem;
color: #ffffff;
color: hsl(var(--color-accent-contrast));
}
@keyframes spin {

View File

@ -59,15 +59,32 @@ export class XMLEditor extends LitElement {
.cm-editor {
border-radius: 0.5rem;
overflow: hidden;
border: 3px solid #000000;
background-color: #ffffff;
border: 3px solid hsl(var(--color-border-contrast));
background-color: hsl(var(--color-background-elevated));
}
.cm-editor.cm-focused {
outline: 2px solid transparent;
box-shadow: 0 0 0 2px #e7f9e4, 0 0 0 calc(4px) #009486;
box-shadow: 0 0 0 2px hsl(var(--color-background-elevated)),
0 0 0 calc(4px) hsl(var(--color-accent-base));
}
.cm-gutters {
background-color: #ffffff !important;
background-color: hsl(var(--color-background-elevated)) !important;
}
.cm-activeLine {
background-color: hsl(var(--color-background-highlight)) !important;
}
.cm-activeLineGutter {
background-color: hsl(var(--color-background-highlight)) !important;
}
.ͼ4 .cm-line {
caret-color: hsl(var(--color-text-base)) !important;
}
.ͼ1 .cm-cursor {
border: none;
}
`;

View File

@ -3,7 +3,8 @@
}
.breadcrumb-item + .breadcrumb-item::before {
@apply inline-block px-1 text-gray-500;
@apply inline-block px-1;
color: hsl(var(--color-text-muted));
content: "/";
}
@ -15,7 +16,7 @@
}
&:focus {
@apply ring-castopod;
@apply ring-accent;
}
}

View File

@ -1,15 +0,0 @@
.chart-map {
height: 600px;
border: solid 10px #eee;
}
.chart-pie {
height: 450px;
width: 100%;
border: solid 1px #eee;
}
.chart-xy {
height: 500px;
width: 100%;
border: solid 1px #eee;
border: solid 3px #eee;
}

View File

@ -19,7 +19,7 @@
.choices.is-disabled .choices__inner,
.choices.is-disabled .choices__input {
background-color: #eaeaea;
opacity: 0.5;
cursor: not-allowed;
-webkit-user-select: none;
-ms-user-select: none;
@ -46,8 +46,8 @@
display: block;
width: 100%;
padding: 10px;
border-bottom: 1px solid #dddddd;
background-color: #ffffff;
border-bottom: 1px solid hsl(var(--color-border-subtle));
background-color: hsl(var(--color-background-elevated));
margin: 0;
}
@ -85,7 +85,8 @@
height: 0;
width: 0;
border-style: solid;
border-color: #333333 transparent transparent transparent;
border-color: hsl(var(--color-text-muted)) transparent transparent
transparent;
border-width: 5px;
position: absolute;
right: 11.5px;
@ -95,7 +96,8 @@
}
.choices[data-type*="select-one"].is-open:after {
border-color: transparent transparent #333333 transparent;
border-color: transparent transparent hsl(var(--color-text-muted))
transparent;
margin-top: -7.5px;
}
@ -138,9 +140,9 @@
}
.choices__inner {
@apply p-2 bg-white border-black rounded-lg border-3;
@apply p-2 rounded-lg border-contrast bg-elevated border-3;
box-shadow: 2px 2px 0 black;
box-shadow: 2px 2px 0 hsl(var(--color-border-contrast));
display: inline-block;
vertical-align: top;
width: 100%;
@ -155,7 +157,7 @@
.is-focused .choices__inner,
.is-open .choices__inner {
@apply ring-castopod ring-inset;
@apply ring-accent ring-inset;
}
.is-open .choices__inner {
@ -190,7 +192,7 @@
}
.choices__list--multiple .choices__item {
@apply inline-block px-2 py-1 mb-1 mr-1 text-sm text-white align-middle rounded bg-pine-500;
@apply inline-block px-2 py-1 mb-1 mr-1 text-sm align-middle rounded text-accent-contrast bg-accent-base;
word-break: break-all;
box-sizing: border-box;
@ -206,7 +208,7 @@
}
.choices__list--multiple .choices__item.is-highlighted {
@apply bg-pine-500;
@apply bg-accent-base;
}
.is-disabled .choices__list--multiple .choices__item {
@ -215,11 +217,11 @@
}
.choices__list--dropdown {
@apply z-50 border-2 border-black shadow-lg;
@apply z-50 border-2 shadow-lg border-contrast;
visibility: hidden;
position: absolute;
width: 100%;
background-color: #ffffff;
background-color: hsl(var(--color-background-elevated));
top: 100%;
margin-top: -1px;
overflow: hidden;
@ -286,7 +288,7 @@
}
.choices__list--dropdown .choices__item--selectable.is-highlighted {
background-color: #f2f2f2;
background-color: hsl(var(--color-background-highlight));
}
.choices__list--dropdown .choices__item--selectable.is-highlighted:after {
@ -334,7 +336,7 @@
}
.choices__input {
@apply mb-1 align-middle bg-white;
@apply mb-1 align-middle bg-elevated;
display: inline-block;
font-size: 14px;

View File

@ -0,0 +1,80 @@
/*
--color-brand-lighter: hsl(173 44% 96%);
--color-brand-light: hsl(111 64% 94%);
--color-brand-base: hsl(174 100% 29%);
--color-brand-dark: hsl(172 100% 17%);
--color-brand-darker: hsl(131 100% 12%);
--color-background-elevated: hsl(0 0% 100%);
--color-background-base: hsl(173 44% 96%);
--color-text-base: hsl(240 17% 2%);
--color-text-muted: hsl(240 8% 63%);
--color-text-inverted: hsl(0 0% 100%);
--color-brand-lighter: 173 44% 96%;
--color-brand-light: 111 64% 94%;
--color-brand-base: 174 100% 29%;
--color-brand-dark: 172 100% 17%;
--color-brand-darker: 131 100% 12%;
--color-background-elevated: 0 0% 100%;
--color-background-base: 173 44% 96%;
--color-text-base: 240 17% 2%;
--color-text-muted: 240 8% 63%;
--color-text-inverted: 0 0% 100%;
*/
/*
--color-accent-base: 0 100% 38%;
--color-accent-hover: 0 100% 48%;
--color-accent-muted: 0 8% 63%;
--color-heading-foreground: 0 64% 94%;
--color-heading-background: 0 100% 17%;
--color-background-elevated: 209 35% 15%;
--color-background-base: 210 34% 13%;
--color-background-navigation: 210 34% 11%;
--color-background-header: 200 38% 15%;
--color-background-highlight: 200 38% 25%;
--color-background-backdrop: 0 0% 50%;
--color-border-subtle: 240 8% 27%;
--color-border-contrast: 240 8% 78%;
--color-border-navigation: 210 34% 4%;
--color-text-base: 240 17% 100%;
--color-text-muted: 240 8% 63%;
*/
@layer base {
:root {
--color-accent-base: 174 100% 29%;
--color-accent-hover: 172 100% 17%;
--color-accent-muted: 131 100% 12%;
--color-accent-contrast: 0 0% 100%;
--color-heading-foreground: 172 100% 17%;
--color-heading-background: 111 64% 94%;
--color-background-elevated: 0 0% 100%;
--color-background-base: 173 44% 96%;
--color-background-navigation: 172 100% 17%;
--color-background-header: 172 100% 17%;
--color-background-highlight: 111 64% 94%;
--color-background-backdrop: 0 0% 50%;
--color-border-subtle: 111 42% 86%;
--color-border-contrast: 0 0% 0%;
--color-border-navigation: 131 100% 12%;
--color-text-base: 158 8% 3%;
--color-text-muted: 172 8% 38%;
}
body {
color: hsl(var(--color-text-base));
}
}

View File

@ -1,12 +1,16 @@
@layer components {
.post-content {
& a {
@apply text-sm font-semibold text-pine-600 hover:underline;
@apply text-sm font-semibold text-accent-base hover:text-accent-hover;
}
}
.ring-castopod {
@apply outline-none ring-2 ring-pine-500 ring-offset-2 ring-offset-pine-100;
.ring-accent {
@apply outline-none ring-2 ring-offset-2;
/* FIXME: why doesn't ring-accent-base work? */
--tw-ring-opacity: 1;
--tw-ring-color: hsl(var(--color-accent-base) / var(--tw-ring-opacity));
--tw-ring-offset-color: hsl(var(--color-background-base));
}
.rounded-conditional-b-xl {
@ -27,30 +31,15 @@
.backdrop-gradient {
background-image: linear-gradient(
180deg,
hsla(0, 0%, 35.29%, 0) 0%,
hsla(0, 0%, 34.53%, 0.034375) 16.36%,
hsla(0, 0%, 32.42%, 0.125) 33.34%,
hsla(0, 0%, 29.18%, 0.253125) 50.1%,
hsla(0, 0%, 24.96%, 0.4) 65.75%,
hsla(0, 0%, 19.85%, 0.546875) 79.43%,
hsla(0, 0%, 13.95%, 0.675) 90.28%,
hsla(0, 0%, 7.32%, 0.765625) 97.43%,
hsla(0, 0%, 0%, 0.8) 100%
);
}
.backdrop-gradient-pine {
background-image: linear-gradient(
180deg,
hsla(172, 100%, 17%, 0) 0%,
hsla(172, 100%, 17%, 0.034375) 16.36%,
hsla(172, 100%, 17%, 0.125) 33.34%,
hsla(172, 100%, 17%, 0.253125) 50.1%,
hsla(172, 100%, 17%, 0.4) 65.75%,
hsla(172, 100%, 17%, 0.546875) 79.43%,
hsla(172, 100%, 17%, 0.675) 90.28%,
hsla(172, 100%, 17%, 0.765625) 97.43%,
hsla(172, 100%, 17%, 0.8) 100%
hsla(0 0% 35.29% / 0) 0%,
hsla(0 0% 34.53% / 0.034375) 16.36%,
hsla(0 0% 32.42% / 0.125) 33.34%,
hsla(0 0% 29.18% / 0.253125) 50.1%,
hsla(0 0% 24.96% / 0.4) 65.75%,
hsla(0 0% 19.85% / 0.546875) 79.43%,
hsla(0 0% 13.95% / 0.675) 90.28%,
hsla(0 0% 7.32% / 0.765625) 97.43%,
hsla(0 0% 0% / 0.8) 100%
);
}
}

View File

@ -24,13 +24,17 @@
@apply relative inline-block px-1 py-2 text-xs text-center cursor-pointer opacity-70 hover:opacity-100;
}
.form-input-tabs > input:focus + label {
@apply ring-accent;
}
.form-input-tabs > input:checked + label::after {
@apply absolute inset-x-0 bottom-0 w-full mx-auto bg-pine-500;
@apply absolute inset-x-0 bottom-0 w-full mx-auto bg-accent-base;
content: "";
height: 0.2rem;
}
.form-input-tabs > input:checked + label {
@apply font-semibold opacity-100 text-pine-500;
@apply font-semibold opacity-100 text-accent-base;
}
}

View File

@ -1,12 +1,12 @@
@import "./tailwind.css";
@import "./custom.css";
@import "./fonts.css";
@import "./colors.css";
@import "./breadcrumb.css";
@import "./dropdown.css";
@import "./choices.css";
@import "./radioBtn.css";
@import "./switch.css";
@import "./charts.css";
@import "./radioToggler.css";
@import "./formInputTabs.css";
@import "./stickyHeader.css";

View File

@ -1,25 +1,22 @@
@layer components {
.form-radio-btn {
@apply absolute mt-3 ml-3 border-black border-3 text-pine-500 focus:ring-castopod;
@apply absolute mt-3 ml-3 border-contrast border-3 text-accent-base;
}
.form-radio-btn:focus + label {
@apply ring-castopod;
}
.form-radio-btn:focus {
@apply ring-0;
@apply ring-accent;
}
.form-radio-btn + label {
@apply inline-block py-2 pl-8 pr-2 text-sm font-semibold text-gray-500 bg-white border-black rounded-lg cursor-pointer border-3;
@apply inline-block py-2 pl-8 pr-2 text-sm font-semibold rounded-lg cursor-pointer border-contrast bg-elevated border-3;
color: hsl(var(--color-text-muted));
}
.form-radio-btn:checked + label {
@apply text-white bg-pine-500;
@apply text-accent-contrast bg-accent-base;
}
.form-radio-btn:checked {
@apply ring-2 ring-black;
@apply ring-2 ring-contrast;
}
}

View File

@ -10,7 +10,11 @@
.see-more_content-fade {
@apply absolute bottom-0 left-0 w-full h-full pointer-events-none;
background-image: linear-gradient(to bottom, transparent, #00564a);
background-image: linear-gradient(
to bottom,
transparent,
hsl(var(--color-background-header))
);
}
.see-more__checkbox {
@ -27,7 +31,7 @@
/* Don't forget focus and hover styles for accessibility! */
.see-more__checkbox:focus ~ .see-more__label {
@apply ring;
@apply ring-accent;
}
.see-more__checkbox:hover ~ .see-more__label {

View File

@ -3,11 +3,11 @@
@apply absolute w-0 h-0 opacity-0;
&:checked + .form-switch-slider {
@apply bg-pine-500;
@apply bg-accent-base;
}
&:focus + .form-switch-slider {
@apply ring-castopod;
@apply ring-accent;
}
&:checked + .form-switch-slider::before {
@ -29,7 +29,7 @@
}
.form-switch-slider {
@apply relative inset-0 flex-shrink-0 w-16 h-8 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3;
@apply relative inset-0 flex-shrink-0 w-16 h-8 transition duration-200 rounded-full cursor-pointer bg-highlight border-contrast border-3;
&.form-switch-slider--small {
@apply w-12 h-6;
@ -46,7 +46,7 @@
}
&::before {
@apply absolute z-10 w-6 h-6 transition duration-200 bg-white rounded-full shadow ring-1 ring-black ring-opacity-5;
@apply absolute z-10 w-6 h-6 transition duration-200 rounded-full shadow bg-elevated ring-1 ring-black ring-opacity-5;
content: "";
left: 1px;
bottom: 1px;

View File

@ -1,5 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -21,7 +21,7 @@ class Alert extends Component
{
$variantClasses = [
'default' => 'text-gray-800 bg-gray-100 border-gray-300',
'success' => 'text-pine-900 bg-pine-100 border-pine-300',
'success' => 'text-pine-900 bg-pine-100 border-castopod-300',
'danger' => 'text-red-900 bg-red-100 border-red-300',
'warning' => 'text-yellow-900 bg-yellow-100 border-yellow-300',
];

View File

@ -28,13 +28,12 @@ class Button extends Component
public function render(): string
{
$baseClass =
'flex-shrink-0 inline-flex items-center justify-center font-semibold shadow-xs rounded-full focus:ring-castopod';
'flex-shrink-0 inline-flex items-center justify-center font-semibold shadow-xs rounded-full focus:ring-accent';
$variantClass = [
'default' => 'text-black bg-gray-300 hover:bg-gray-400',
'primary' => 'text-white bg-pine-500 hover:bg-pine-800',
'secondary' => 'border-2 border-pine-500 text-pine-500 bg-pine-100 hover:border-pine-800 hover:text-pine-800',
'accent' => 'text-white bg-rose-600 hover:bg-rose-800',
'primary' => 'text-accent-contrast bg-accent-base hover:bg-accent-hover',
'secondary' => 'border-2 border-accent-base text-accent-base bg-transparent hover:border-accent-hover hover:text-accent-hover',
'success' => 'text-white bg-pine-500 hover:bg-pine-800',
'danger' => 'text-white bg-red-600 hover:bg-red-700',
'warning' => 'text-black bg-yellow-500 hover:bg-yellow-600',

View File

@ -17,7 +17,7 @@ class ChartsComponent extends Component
public function render(): string
{
return <<<HTML
<div class="bg-white border rounded-xl border-pine-100 {$this->class}">
<div class="bg-elevated border-3 rounded-xl border-subtle {$this->class}">
<h2 class="px-6 py-4 text-xl">{$this->title}</h2>
<div class="w-full h-[500px]" data-chart-type="{$this->type}" data-chart-url="{$this->dataUrl}"></div>
</div>

View File

@ -35,14 +35,14 @@ class DropdownMenu extends Component
switch ($item['type']) {
case 'link':
$menuItems .= anchor($item['uri'], $item['title'], [
'class' => 'px-4 py-1 hover:bg-gray-100 focus:ring-castopod focus:ring-inset' . (array_key_exists('class', $item) ? ' ' . $item['class'] : ''),
'class' => 'px-4 py-1 hover:bg-highlight focus:ring-accent focus:ring-inset' . (array_key_exists('class', $item) ? ' ' . $item['class'] : ''),
]);
break;
case 'html':
$menuItems .= html_entity_decode($item['content']);
break;
case 'separator':
$menuItems .= '<hr class="my-2 border border-gray-100">';
$menuItems .= '<hr class="my-2 border border-subtle">';
break;
default:
break;
@ -51,7 +51,7 @@ class DropdownMenu extends Component
return <<<HTML
<nav id="{$this->id}"
class="absolute z-50 flex flex-col py-2 text-black whitespace-no-wrap bg-white border-black rounded-lg border-3"
class="absolute z-50 flex flex-col py-2 whitespace-no-wrap rounded-lg text-skin-base border-contrast bg-elevated border-3"
aria-labelledby="{$this->labelledby}"
data-dropdown="menu"
data-dropdown-placement="{$this->placement}"

View File

@ -20,7 +20,7 @@ class Checkbox extends FormComponent
$attributes = [
'id' => $this->value,
'name' => $this->name,
'class' => 'form-checkbox text-pine-500 border-black border-3 focus:ring-castopod w-6 h-6',
'class' => 'form-checkbox bg-elevated text-accent-base border-contrast border-3 focus:ring-accent w-6 h-6',
];
if ($this->required) {
$attributes['required'] = 'required';

View File

@ -18,9 +18,9 @@ class DatetimePicker extends FormComponent
$closeIcon = icon('close');
return <<<HTML
<div class="flex border-3 rounded-lg border-black focus-within:ring-castopod {$this->class}" data-picker="datetime">
<div class="flex border-3 rounded-lg border-contrast focus-within:ring-accent {$this->class}" data-picker="datetime">
{$dateInput}
<button class="p-3 bg-white hover:bg-pine-100 rounded-r-md focus:ring-inset focus:ring-castopod" type="button" aria-label="{$clearLabel}" title="{$clearLabel}" data-clear="">
<button class="p-3 bg-elevated hover:bg-base rounded-r-md focus:ring-inset focus:ring-accent" type="button" aria-label="{$clearLabel}" title="{$clearLabel}" data-clear="">
{$closeIcon}
</button>
</div>

View File

@ -13,7 +13,7 @@ class Helper extends FormComponent
public function render(): string
{
$class = 'text-gray-600';
$class = 'text-skin-muted';
return <<<HTML
<small id="{$this->id}" class="{$class} {$this->class}">{$this->slot}</small>

View File

@ -10,12 +10,12 @@ class Input extends FormComponent
public function render(): string
{
$baseClass = 'w-full bg-white border-black rounded-lg focus:border-black border-3 focus:ring-castopod focus-within:ring-castopod ' . $this->class;
$baseClass = 'w-full bg-elevated border-contrast rounded-lg focus:border-contrast border-3 focus:ring-accent focus-within:ring-accent ' . $this->class;
$this->attributes['class'] = $baseClass;
if ($this->type === 'file') {
$this->attributes['class'] .= ' file:px-3 file:py-2 file:h-[40px] file:font-semibold file:text-gray-800 file:text-sm file:rounded-none file:border-none file:bg-gray-200 file:hover:bg-gray-300 file:cursor-pointer';
$this->attributes['class'] .= ' file:px-3 file:py-2 file:h-[40px] file:font-semibold file:text-skin-muted file:text-sm file:rounded-none file:border-none file:bg-highlight file:cursor-pointer';
} else {
$this->attributes['class'] .= ' px-3 py-2';
}

View File

@ -8,9 +8,9 @@ class MarkdownEditor extends FormComponent
{
public function render(): string
{
$editorClass = 'w-full flex flex-col bg-white border-3 border-black rounded-lg overflow-hidden focus-within:ring-castopod ' . $this->class;
$editorClass = 'w-full flex flex-col bg-elevated border-3 border-contrast rounded-lg overflow-hidden focus-within:ring-accent ' . $this->class;
$this->attributes['class'] = 'border-none focus:border-none focus:outline-none focus:ring-0 w-full h-full';
$this->attributes['class'] = 'bg-elevated border-none focus:border-none focus:outline-none focus:ring-0 w-full h-full';
$this->attributes['rows'] = 6;
$textarea = form_textarea($this->attributes, old($this->name, html_entity_decode($this->value), false));
@ -25,7 +25,7 @@ class MarkdownEditor extends FormComponent
'image-add' => icon('image-add'),
'markdown' => icon(
'markdown',
'mr-1 text-lg text-gray-400'
'mr-1 text-lg opacity-40'
),
];
$translations = [
@ -37,35 +37,35 @@ class MarkdownEditor extends FormComponent
return <<<HTML
<div class="{$editorClass}">
<header class="px-2">
<div class="sticky top-0 z-20 flex flex-wrap justify-between bg-white border-b border-gray-300">
<div class="sticky top-0 z-20 flex flex-wrap justify-between border-b border-gray-300 bg-elevated">
<markdown-write-preview for="{$this->id}" class="relative inline-flex h-8">
<button type="button" slot="write" class="px-2 font-semibold focus:ring-inset focus:ring-castopod">{$translations['write']}</button>
<button type="button" slot="preview" class="px-2 font-semibold focus:ring-inset focus:ring-castopod">{$translations['preview']}</button>
<button type="button" slot="write" class="px-2 font-semibold focus:ring-inset focus:ring-accent">{$translations['write']}</button>
<button type="button" slot="preview" class="px-2 font-semibold focus:ring-inset focus:ring-accent">{$translations['preview']}</button>
</markdown-write-preview>
<markdown-toolbar for="{$this->id}" class="flex gap-4 px-2 py-1">
<div class="inline-flex text-2xl gap-x-1">
<md-header class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['heading']}</md-header>
<md-bold class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['bold']}</md-bold>
<md-italic class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['italic']}</md-italic>
<md-header class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['heading']}</md-header>
<md-bold class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['bold']}</md-bold>
<md-italic class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['italic']}</md-italic>
</div>
<div class="inline-flex text-2xl gap-x-1">
<md-unordered-list class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['list-unordered']}</md-unordered-list>
<md-ordered-list class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['list-ordered']}</md-ordered-list>
<md-unordered-list class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['list-unordered']}</md-unordered-list>
<md-ordered-list class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['list-ordered']}</md-ordered-list>
</div>
<div class="inline-flex text-2xl gap-x-1">
<md-quote class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['quote']}</md-quote>
<md-link class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['link']}</md-link>
<md-image class="opacity-50 hover:opacity-100 focus:ring-castopod focus:opacity-100">{$icons['image-add']}</md-image>
<md-quote class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['quote']}</md-quote>
<md-link class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['link']}</md-link>
<md-image class="opacity-50 hover:opacity-100 focus:ring-accent focus:opacity-100">{$icons['image-add']}</md-image>
</div>
</markdown-toolbar>
</div>
</header>
<div class="relative">
{$textarea}
<markdown-preview for="{$this->id}" class="absolute top-0 left-0 hidden w-full h-full p-2 overflow-y-auto prose bg-gray-50" showClass="bg-white" />
<markdown-preview for="{$this->id}" class="absolute top-0 left-0 hidden w-full h-full max-w-full px-3 py-2 overflow-y-auto prose bg-base" showClass="bg-elevated" />
</div>
<footer class="flex px-2 py-1 border-t bg-gray-50">
<a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-gray-500 hover:text-gray-700" target="_blank" rel="noopener noreferrer">{$icons['markdown']}{$translations['help']}</a>
<footer class="flex px-2 py-1 border-t bg-base">
<a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-skin-muted hover:text-skin-base" target="_blank" rel="noopener noreferrer">{$icons['markdown']}{$translations['help']}</a>
</footer>
</div>
HTML;

View File

@ -37,7 +37,7 @@ class MultiSelect extends FormComponent
'data-no-choices-text' => lang('Common.forms.multiSelect.noChoicesText'),
'data-max-item-text' => lang('Common.forms.multiSelect.maxItemText'),
];
$this->attributes['class'] .= ' border-3 border-black rounded-lg';
$this->attributes['class'] .= ' bg-elevated border-3 border-contrast rounded-lg';
$extra = array_merge($defaultAttributes, $this->attributes);
return form_dropdown($this->name, $this->options, $this->selected, $extra);

View File

@ -19,7 +19,7 @@ class Radio extends FormComponent
[
'id' => $this->value,
'name' => $this->name,
'class' => 'text-pine-500 border-black border-3 focus:ring-castopod w-6 h-6',
'class' => 'text-accent-base bg-elevated border-contrast border-3 focus:ring-accent w-6 h-6',
],
$this->value,
old($this->name) ? old($this->name) === $this->value : $this->isChecked,

View File

@ -19,7 +19,7 @@ class RadioButton extends FormComponent
[
'id' => $this->value,
'name' => $this->name,
'class' => 'form-radio-btn',
'class' => 'form-radio-btn bg-elevated',
],
$this->value,
old($this->name) ? old($this->name) === $this->value : $this->isChecked,

View File

@ -16,10 +16,10 @@ class Section extends Component
public function render(): string
{
$subtitle = $this->subtitle === null ? '' : '<p class="text-sm text-gray-600 clear-left ' . $this->subtitleClass . '">' . $this->subtitle . '</p>';
$subtitle = $this->subtitle === null ? '' : '<p class="text-sm clear-left text-skin-muted ' . $this->subtitleClass . '">' . $this->subtitle . '</p>';
return <<<HTML
<fieldset class="w-full max-w-xl p-8 bg-white border-3 border-pine-100 rounded-xl {$this->class}">
<fieldset class="w-full max-w-xl p-8 bg-elevated border-3 border-subtle rounded-xl {$this->class}">
<Heading tagName="legend" class="float-left">{$this->title}</Heading>
{$subtitle}
<div class="flex flex-col gap-4 py-4 clear-left">{$this->slot}</div>

View File

@ -21,7 +21,7 @@ class Select extends FormComponent
public function render(): string
{
$defaultAttributes = [
'class' => 'focus:border-black focus:ring-castopod border-3 rounded-lg border-black ' . $this->class,
'class' => 'focus:border-contrast focus:ring-accent border-3 rounded-lg bg-elevated border-contrast ' . $this->class,
'data-class' => $this->class,
'data-select-text' => lang('Common.forms.multiSelect.selectText'),
'data-loading-text' => lang('Common.forms.multiSelect.loadingText'),

View File

@ -17,7 +17,7 @@ class Textarea extends FormComponent
{
unset($this->attributes['value']);
$this->attributes['class'] = 'w-full focus:border-black focus:ring-castopod rounded-lg border-3 border-black ' . $this->class;
$this->attributes['class'] = 'bg-elevated w-full focus:border-contrast focus:ring-accent rounded-lg border-3 border-contrast ' . $this->class;
$textarea = form_textarea(
$this->attributes,

View File

@ -23,7 +23,7 @@ class Heading extends Component
'large' => 'text-3xl',
];
$class = $this->class . ' relative z-10 font-bold text-pine-800 font-display before:w-full before:absolute before:h-1/2 before:left-0 before:bottom-0 before:rounded-full before:bg-pine-100 before:z-[-10] ' . $sizeClasses[$this->size];
$class = $this->class . ' relative z-10 font-bold text-heading-foreground font-display before:w-full before:absolute before:h-1/2 before:left-0 before:bottom-0 before:rounded-full before:bg-heading-background before:z-[-10] ' . $sizeClasses[$this->size];
return <<<HTML
<{$this->tagName} class="{$class}">{$this->slot}</{$this->tagName}>

View File

@ -15,8 +15,7 @@ class IconButton extends Component
$attributes = [
'isSquared' => 'true',
'title' => $this->slot,
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
];
$attributes = array_merge($attributes, $this->attributes);

View File

@ -8,18 +8,18 @@
<?= service('vite')->asset('styles/index.css', 'css') ?>
</head>
<body class="flex flex-col items-center justify-center min-h-screen px-2 text-center bg-gray-100">
<body class="flex flex-col items-center justify-center min-h-screen px-2 text-center bg-base">
<?= svg('castopod-mascot_confused', 'h-64') ?>
<h1 class="text-3xl font-bold font-display md:text-4xl lg:text-5xl">404 - File Not Found</h1>
<p class="mb-6 text-lg text-gray-600 md:text-xl lg:text-2xl">
<p class="mb-6 text-lg text-skin-muted md:text-xl lg:text-2xl">
<?php if (isset($message) && $message !== '(null)'): ?>
<?= esc($message) ?>
<?php else: ?>
Sorry! Cannot seem to find the page you were looking for.
<?php endif; ?>
</p>
<button class="inline-flex items-center justify-center px-3 py-1 text-sm font-semibold text-white rounded-full shadow-xs focus:ring-castopod md:px-4 md:py-2 md:text-base bg-pine-500 hover:bg-pine-800"><?= lang('Common.go_back') ?></button>
<button class="inline-flex items-center justify-center px-3 py-1 text-sm font-semibold rounded-full shadow-xs text-accent-contrast focus:ring-accent md:px-4 md:py-2 md:text-base bg-accent-base hover:bg-accent-hover"><?= lang('Common.go_back') ?></button>
</body>
</html>

View File

@ -10,10 +10,10 @@
<?= service('vite')->asset('styles/index.css', 'css') ?>
</head>
<body class="flex flex-col items-center justify-center min-h-screen px-2 text-center bg-gray-100">
<body class="flex flex-col items-center justify-center min-h-screen px-2 text-center bg-base">
<?= svg('castopod-mascot_confused', 'h-64') ?>
<h1 class="text-3xl font-bold font-display md:text-4xl lg:text-5xl">Whoops!</h1>
<p class="mb-6 text-lg text-gray-600 md:text-xl lg:text-2xl">We seem to have hit a snag. Please try again later...</p>
<p class="mb-6 text-lg text-skin-muted md:text-xl lg:text-2xl">We seem to have hit a snag. Please try again later...</p>
</body>
</html>

View File

@ -12,14 +12,14 @@ $pager->setSurroundCount(2);
<li>
<a href="<?= $pager->getFirst() ?>" aria-label="<?= lang(
'Pager.first',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.first') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getPreviousPage() ?>" aria-label="<?= lang(
'Pager.previous',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang(
'Pager.previous',
) ?></span>
@ -30,13 +30,13 @@ $pager->setSurroundCount(2);
<?php foreach ($pager->links() as $link): ?>
<li>
<?php if ($link['active']): ?>
<span class="block px-4 py-2 font-semibold text-white rounded-full bg-pine-500">
<span class="block px-4 py-2 font-semibold rounded-full text-accent-contrast bg-accent-base">
<?= $link['title'] ?>
</span>
<?php else: ?>
<a href="<?= $link[
'uri'
] ?>" class="block px-4 py-2 text-gray-700 rounded-full hover:bg-gray-200 hover:text-black">
] ?>" class="block px-4 py-2 rounded-full text-skin-muted hover:bg-highlight">
<?= $link['title'] ?>
</a>
<?php endif; ?>
@ -47,14 +47,14 @@ $pager->setSurroundCount(2);
<li>
<a href="<?= $pager->getNextPage() ?>" aria-label="<?= lang(
'Pager.next',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.next') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getLast() ?>" aria-label="<?= lang(
'Pager.last',
) ?>" class="block px-3 py-2 text-gray-700 hover:bg-gray-200 hover:text-black">
) ?>" class="block px-3 py-2 text-skin-muted hover:bg-highlight">
<span aria-hidden="true"><?= lang('Pager.last') ?></span>
</a>
</li>

View File

@ -135,7 +135,7 @@ class Post extends UuidEntity
public function getHasReplies(): bool
{
return $this->getReplies() !== null;
return $this->getReplies() !== [];
}
public function getReplyToPost(): ?self

30
package-lock.json generated
View File

@ -27,32 +27,32 @@
"leaflet": "^1.7.1",
"leaflet.markercluster": "^1.5.3",
"lit": "^2.0.2",
"marked": "^3.0.7",
"marked": "^3.0.8",
"xml-formatter": "^2.5.1"
},
"devDependencies": {
"@commitlint/cli": "^13.2.1",
"@commitlint/config-conventional": "^13.2.0",
"@semantic-release/changelog": "^6.0.0",
"@semantic-release/exec": "^6.0.1",
"@semantic-release/git": "^10.0.0",
"@semantic-release/gitlab": "^7.0.3",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/exec": "^6.0.2",
"@semantic-release/git": "^10.0.1",
"@semantic-release/gitlab": "^7.0.4",
"@tailwindcss/forms": "^0.4.0-alpha.1",
"@tailwindcss/line-clamp": "^0.2.2",
"@tailwindcss/typography": "^0.5.0-alpha.2",
"@types/leaflet": "^1.7.5",
"@types/marked": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"@types/marked": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"cross-env": "^7.0.3",
"cssnano": "^5.0.8",
"cssnano": "^5.0.9",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.0.1",
"eslint": "^8.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"is-ci": "^3.0.0",
"lint-staged": "^11.2.3",
"is-ci": "^3.0.1",
"lint-staged": "^11.2.6",
"postcss-import": "^14.0.2",
"postcss-nesting": "^8.0.1",
"postcss-preset-env": "^6.7.0",
@ -60,12 +60,12 @@
"prettier": "2.4.1",
"prettier-plugin-organize-imports": "^2.3.4",
"semantic-release": "^18.0.0",
"stylelint": "^14.0.0",
"stylelint": "^14.0.1",
"stylelint-config-standard": "^23.0.0",
"svgo": "^2.7.0",
"svgo": "^2.8.0",
"tailwindcss": "^3.0.0-alpha.1",
"typescript": "^4.4.4",
"vite": "^2.6.10"
"vite": "^2.6.13"
}
},
"node_modules/@amcharts/amcharts4": {

View File

@ -45,32 +45,32 @@
"leaflet": "^1.7.1",
"leaflet.markercluster": "^1.5.3",
"lit": "^2.0.2",
"marked": "^3.0.7",
"marked": "^3.0.8",
"xml-formatter": "^2.5.1"
},
"devDependencies": {
"@commitlint/cli": "^13.2.1",
"@commitlint/config-conventional": "^13.2.0",
"@semantic-release/changelog": "^6.0.0",
"@semantic-release/exec": "^6.0.1",
"@semantic-release/git": "^10.0.0",
"@semantic-release/gitlab": "^7.0.3",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/exec": "^6.0.2",
"@semantic-release/git": "^10.0.1",
"@semantic-release/gitlab": "^7.0.4",
"@tailwindcss/forms": "^0.4.0-alpha.1",
"@tailwindcss/line-clamp": "^0.2.2",
"@tailwindcss/typography": "^0.5.0-alpha.2",
"@types/leaflet": "^1.7.5",
"@types/marked": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"@types/marked": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"cross-env": "^7.0.3",
"cssnano": "^5.0.8",
"cssnano": "^5.0.9",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.0.1",
"eslint": "^8.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"is-ci": "^3.0.0",
"lint-staged": "^11.2.3",
"is-ci": "^3.0.1",
"lint-staged": "^11.2.6",
"postcss-import": "^14.0.2",
"postcss-nesting": "^8.0.1",
"postcss-preset-env": "^6.7.0",
@ -78,12 +78,12 @@
"prettier": "2.4.1",
"prettier-plugin-organize-imports": "^2.3.4",
"semantic-release": "^18.0.0",
"stylelint": "^14.0.0",
"stylelint": "^14.0.1",
"stylelint-config-standard": "^23.0.0",
"svgo": "^2.7.0",
"svgo": "^2.8.0",
"tailwindcss": "^3.0.0-alpha.1",
"typescript": "^4.4.4",
"vite": "^2.6.10"
"vite": "^2.6.13"
},
"lint-staged": {
"*.{js,ts,css,md,json}": "prettier --write",

View File

@ -1,6 +1,15 @@
/* eslint-disable */
const defaultTheme = require("tailwindcss/defaultTheme");
function withOpacity(variableName) {
return ({ opacityValue }) => {
if (opacityValue !== undefined) {
return `hsl(var(${variableName}) / ${opacityValue})`;
}
return `hsl(var(${variableName}))`;
};
}
module.exports = {
content: [
"./app/Views/**/*.php",
@ -15,7 +24,58 @@ module.exports = {
sans: ["Inter", ...defaultTheme.fontFamily.sans],
display: ["Kumbh Sans", ...defaultTheme.fontFamily.sans],
},
textColor: {
skin: {
base: withOpacity("--color-text-base"),
muted: withOpacity("--color-text-muted"),
},
accent: {
base: withOpacity("--color-accent-base"),
hover: withOpacity("--color-accent-hover"),
muted: withOpacity("--color-accent-muted"),
contrast: withOpacity("--color-accent-contrast"),
},
},
backgroundColor: {
base: withOpacity("--color-background-base"),
elevated: withOpacity("--color-background-elevated"),
navigation: withOpacity("--color-background-navigation"),
backdrop: withOpacity("--color-background-backdrop"),
header: withOpacity("--color-background-header"),
accent: {
base: withOpacity("--color-accent-base"),
hover: withOpacity("--color-accent-hover"),
},
highlight: withOpacity("--color-background-highlight"),
},
borderColor: {
subtle: withOpacity("--color-border-subtle"),
contrast: withOpacity("--color-border-contrast"),
navigation: withOpacity("--color-border-navigation"),
accent: {
base: withOpacity("--color-accent-base"),
hover: withOpacity("--color-accent-hover"),
},
background: {
base: withOpacity("--color-background-base"),
elevated: withOpacity("--color-background-elevated"),
},
},
ringColor: {
contrast: withOpacity("--color-border-contrast"),
background: {
base: withOpacity("--color-background-base"),
elevated: withOpacity("--color-background-elevated"),
},
},
colors: {
background: {
header: withOpacity("--color-background-header"),
},
heading: {
foreground: withOpacity("--color-heading-foreground"),
background: withOpacity("--color-heading-background"),
},
pine: {
50: "#F2FAF9",
100: "#E7F9E4",
@ -54,6 +114,9 @@ module.exports = {
borderWidth: {
3: "3px",
},
ringWidth: {
3: "3px",
},
},
},
variants: {},

View File

@ -20,19 +20,19 @@
->asset('js/admin-audio-player.ts', 'js') ?>
</head>
<body class="relative grid items-start min-h-screen bg-pine-50 grid-cols-admin grid-rows-admin">
<body class="relative grid items-start min-h-screen bg-base grid-cols-admin grid-rows-admin">
<?= $this->include('_partials/_nav_header') ?>
<?= $this->include('_partials/_nav_aside') ?>
<main class="relative max-w-full col-start-1 row-start-2 col-span-full md:col-start-2 md:col-span-1">
<header class="z-40 flex items-center px-4 bg-white border-b md:px-12 sticky-header-outer border-pine-100">
<header class="z-40 flex items-center px-4 border-b bg-elevated md:px-12 sticky-header-outer border-subtle">
<div class="flex flex-col justify-end w-full -mt-4 sticky-header-inner">
<?= render_breadcrumb('text-gray-800 text-xs items-center flex') ?>
<?= render_breadcrumb('text-xs items-center flex') ?>
<div class="flex justify-between py-1">
<div class="flex flex-wrap items-center overflow-x-hidden">
<Heading tagName="h1" size="large" class="truncate"><?= $this->renderSection('pageTitle') ?></Heading>
<?= $this->renderSection('headerLeft') ?>
</div>
<div class="flex flex-shrink-0 gap-1"><?= $this->renderSection('headerRight') ?></div>
<div class="flex flex-shrink-0 gap-x-2"><?= $this->renderSection('headerRight') ?></div>
</div>
</div>
</header>

View File

@ -1,5 +1,5 @@
<div data-sidebar-toggler="backdrop" role="button" tabIndex="0" aria-label="Close" class="fixed z-50 hidden w-full h-full bg-gray-800/75 md:hidden"></div>
<aside data-sidebar-toggler="sidebar" data-toggle-class="-translate-x-full" data-hide-class="-translate-x-full" class="h-full max-h-[calc(100vh-40px)] sticky z-50 flex flex-col row-start-2 col-start-1 text-white transition duration-200 ease-in-out transform -translate-x-full border-r top-10 border-pine-900 bg-pine-800 md:translate-x-0">
<aside data-sidebar-toggler="sidebar" data-toggle-class="-translate-x-full" data-hide-class="-translate-x-full" class="h-full max-h-[calc(100vh-40px)] sticky z-50 flex flex-col row-start-2 col-start-1 text-white transition duration-200 ease-in-out transform -translate-x-full border-r top-10 border-navigation bg-navigation md:translate-x-0">
<?php if (isset($podcast) && isset($episode)): ?>
<?= $this->include('episode/_sidebar') ?>
<?php elseif (isset($podcast)): ?>
@ -10,7 +10,7 @@
<footer class="px-2 py-2 mx-auto text-xs text-right">
<?= lang('Common.powered_by', [
'castopod' =>
'<a class="inline-flex font-semibold hover:underline focus:ring-castopod" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a> ' .
'<a class="inline-flex font-semibold hover:underline focus:ring-accent" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a> ' .
CP_VERSION,
]) ?>
</footer>

View File

@ -1,23 +1,23 @@
<header class="sticky top-0 z-[60] flex items-center h-10 text-white border-b col-span-full bg-pine-800 border-pine-900">
<header class="sticky top-0 z-[60] flex items-center h-10 text-white border-b col-span-full bg-navigation border-navigation">
<button type="button"
data-sidebar-toggler="toggler"
class="h-full pr-1 text-xl md:hidden focus:ring-castopod focus:ring-inset"><?= icon('menu') ?></button>
class="h-full pr-1 text-xl md:hidden focus:ring-accent focus:ring-inset"><?= icon('menu') ?></button>
<div class="inline-flex items-center h-full">
<a href="<?= route_to(
'admin',
) ?>" class="inline-flex items-center h-full px-2 border-r border-pine-900 focus:ring-inset focus:ring-castopod">
) ?>" class="inline-flex items-center h-full px-2 border-r border-navigation focus:ring-inset focus:ring-accent">
<?= (isset($podcast) ? icon('arrow-left', 'mr-2') : '') . svg('castopod-logo-base', 'h-6') ?>
</a>
<a href="<?= route_to(
'home',
) ?>" class="inline-flex items-center h-full px-6 text-sm font-semibold hover:underline focus:ring-inset focus:ring-castopod">
) ?>" class="inline-flex items-center h-full px-6 text-sm font-semibold hover:underline focus:ring-inset focus:ring-accent">
<?= lang('AdminNavigation.go_to_website') ?>
<?= icon('external-link', 'ml-1 opacity-60') ?>
</a>
</div>
<button
type="button"
class="inline-flex items-center h-full px-3 ml-auto text-sm font-semibold focus:ring-inset focus:ring-castopod gap-x-2"
class="inline-flex items-center h-full px-3 ml-auto text-sm font-semibold focus:ring-inset focus:ring-accent gap-x-2"
id="my-account-dropdown"
data-dropdown="button"
data-dropdown-target="my-account-dropdown-menu"
@ -25,17 +25,17 @@
aria-expanded="false"><div class="relative mr-1">
<?= icon('account-circle', 'text-3xl opacity-60') ?>
<?= user()
->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 border rounded-full -right-1 border-pine-800" />' ?>
->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 rounded-full -right-1" />' ?>
</div>
<?= user()->username ?>
<?= icon('caret-down', 'ml-auto text-2xl') ?></button>
<?php
$interactButtons = '';
foreach (user()->podcasts as $userPodcast) {
$checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-pine-800 text-white rounded-full') : '';
$checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-accent-base text-accent-contrast rounded-full') : '';
$interactButtons .= <<<CODE_SAMPLE
<button class="inline-flex items-center w-full px-4 py-1 hover:bg-gray-100" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
<button class="inline-flex items-center w-full px-4 py-1 hover:bg-highlight" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
<span class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" />{$userPodcast->title}{$checkMark}</span>
</button>
CODE_SAMPLE;
@ -71,8 +71,8 @@
[
'type' => 'html',
'content' => esc(<<<CODE_SAMPLE
<nav class="flex flex-col py-2 text-black whitespace-no-wrap">
<span class="px-4 mb-2 text-xs font-semibold tracking-wider text-gray-500 uppercase">{$interactAsText}</span>
<nav class="flex flex-col py-2 whitespace-no-wrap">
<span class="px-4 mb-2 text-xs font-semibold tracking-wider uppercase text-skin-muted">{$interactAsText}</span>
<form action="{$route}" method="POST" class="flex flex-col">
{$csrfField}
{$interactButtons}

View File

@ -1,32 +1,32 @@
<div class="px-4 py-5">
<dt class="text-sm font-medium leading-5 text-gray-500">
<dt class="text-sm font-medium leading-5 text-skin-muted">
<?= lang('User.form.email') ?>
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900">
<dd class="mt-1 text-sm leading-5">
<?= $user->email ?>
</dd>
</div>
<div class="px-4 py-5">
<dt class="text-sm font-medium leading-5 text-gray-500">
<dt class="text-sm font-medium leading-5 text-skin-muted">
<?= lang('User.form.username') ?>
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900">
<dd class="mt-1 text-sm leading-5">
<?= $user->username ?>
</dd>
</div>
<div class="px-4 py-5">
<dt class="text-sm font-medium leading-5 text-gray-500">
<dt class="text-sm font-medium leading-5 text-skin-muted">
<?= lang('User.form.roles') ?>
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900">
<dd class="mt-1 text-sm leading-5">
<?= implode(', ', $user->roles) ?>
</dd>
</div>
<div class="px-4 py-5">
<dt class="text-sm font-medium leading-5 text-gray-500">
<dt class="text-sm font-medium leading-5 text-skin-muted">
<?= lang('User.form.permissions') ?>
</dt>
<dd class="max-w-xl mt-1 text-sm leading-5 text-gray-900">
<dd class="max-w-xl mt-1 text-sm leading-5">
<?= implode(', ', $user->permissions) ?>
</dd>
</div>

View File

@ -31,7 +31,7 @@ $navigation = [
<nav class="flex flex-col flex-1 py-4 overflow-y-auto gap-y-4">
<?php foreach ($navigation as $section => $data): ?>
<div>
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-castopod" type="button">
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-accent" type="button">
<?= icon($data['icon'], 'opacity-60 text-2xl mr-4') ?>
<?= lang('AdminNavigation.' . $section) ?>
</button>
@ -39,7 +39,7 @@ $navigation = [
<?php foreach ($data['items'] as $item): ?>
<?php $isActive = url_is(route_to($item)); ?>
<li class="inline-flex">
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-castopod<?= $isActive
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-accent<?= $isActive
? ' font-semibold opacity-100 inline-flex items-center'
: ' opacity-75' ?>" href="<?= route_to($item) ?>"><?= ($isActive ? icon('chevron-right', 'mr-2') : '') . lang(
'AdminNavigation.' . $item,

View File

@ -9,19 +9,19 @@
<?= $this->section('content') ?>
<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium leading-5 text-gray-500">
<div class="px-4 py-5 bg-base sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium leading-5 text-skin-muted">
Username
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<dd class="mt-1 text-sm leading-5 sm:mt-0 sm:col-span-2">
<?= $contributor->username ?>
</dd>
</div>
<div class="px-4 py-5 bg-gray-50 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium leading-5 text-gray-500">
<div class="px-4 py-5 bg-base sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium leading-5 text-skin-muted">
Role
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<dd class="mt-1 text-sm leading-5 sm:mt-0 sm:col-span-2">
<?= $contributor->podcast_role ?>
</dd>
</div>

View File

@ -1,4 +1,4 @@
<article class="relative flex flex-col flex-1 flex-shrink-0 w-full transition group overflow-hidden bg-white border-2 snap-center hover:shadow-lg focus-within:shadow-lg focus-within:ring-castopod border-pine-100 rounded-xl min-w-[12rem] max-w-[17rem]">
<article class="relative flex flex-col flex-1 flex-shrink-0 w-full transition group overflow-hidden bg-elevated border-3 snap-center hover:shadow-lg focus-within:shadow-lg focus-within:ring-accent border-subtle rounded-xl min-w-[12rem] max-w-[17rem]">
<a href="<?= route_to('episode-view', $episode->podcast->id, $episode->id) ?>" class="flex flex-col justify-end w-full h-full text-white group">
<div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient"></div>
<div class="w-full h-full overflow-hidden">
@ -10,7 +10,7 @@
<span class="font-semibold leading-tight line-clamp-2"><?= $episode->title ?></span>
</div>
</a>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-castopod focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $episode->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $episode->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<DropdownMenu id="more-dropdown-<?= $episode->id ?>-menu" labelledby="more-dropdown-<?= $episode->id ?>" offsetY="-32" items="<?= esc(json_encode([
[
'type' => 'link',

View File

@ -7,7 +7,7 @@ $podcastNavigation = [
],
]; ?>
<a href="<?= route_to('podcast-view', $podcast->id) ?>" class="flex items-center px-4 py-2 border-b border-pine-900 focus:ring-inset focus:ring-castopod">
<a href="<?= route_to('podcast-view', $podcast->id) ?>" class="flex items-center px-4 py-2 focus:ring-inset focus:ring-accent">
<?= icon('arrow-left', 'mr-2') ?>
<img
src="<?= $podcast->cover->tiny_url ?>"
@ -16,7 +16,7 @@ $podcastNavigation = [
/>
<span class="flex-1 w-full px-2 text-xs font-semibold truncate" title="<?= $podcast->title ?>"><?= $podcast->title ?></span>
</a>
<div class="flex items-center px-4 py-2 border-b border-pine-900">
<div class="flex items-center px-4 py-2 border-t border-b border-navigation">
<img
src="<?= $episode->cover->thumbnail_url ?>"
alt="<?= $episode->title ?>"
@ -28,7 +28,7 @@ $podcastNavigation = [
'episode',
$podcast->handle,
$episode->slug,
) ?>" class="inline-flex items-center text-xs hover:underline focus:ring-castopod"><?= lang(
) ?>" class="inline-flex items-center text-xs hover:underline focus:ring-accent"><?= lang(
'EpisodeNavigation.go_to_page',
) ?>
<?= icon('external-link', 'ml-1 opacity-60') ?>
@ -38,7 +38,7 @@ $podcastNavigation = [
<nav class="flex flex-col flex-1 py-4 overflow-y-auto gap-y-4">
<?php foreach ($podcastNavigation as $section => $data): ?>
<div>
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-castopod" type="button">
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-accent" type="button">
<?= icon($data['icon'], 'opacity-60 text-2xl mr-4') .
lang('EpisodeNavigation.' . $section) ?>
</button>
@ -46,7 +46,7 @@ $podcastNavigation = [
<?php foreach ($data['items'] as $item): ?>
<?php $isActive = url_is(route_to($item, $podcast->id, $episode->id)); ?>
<li class="inline-flex">
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-castopod <?= $isActive
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-accent <?= $isActive
? 'font-semibold opacity-100 inline-flex items-center'
: 'opacity-75' ?>" href="<?= route_to(
$item,

View File

@ -162,10 +162,10 @@
<div class="py-2 tab-panels">
<section id="transcript-file-upload" class="flex items-center tab-panel">
<?php if ($episode->transcript_file) : ?>
<div class="flex justify-between">
<div class="flex mb-1 gap-x-2">
<?= anchor(
$episode->transcript_file_url,
icon('file', 'mr-2 text-gray-500') .
icon('file', 'mr-2 text-skin-muted') .
$episode->transcript_file,
[
'class' => 'inline-flex items-center text-xs',
@ -182,9 +182,8 @@
icon('delete-bin', 'mx-auto'),
[
'class' =>
'p-1 bg-red-200 rounded-full text-red-700 hover:text-red-900',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'p-1 text-sm bg-red-100 rounded-full text-red-700 hover:text-red-900 focus:ring-accent',
'data-tooltip' => 'bottom',
'title' => lang(
'Episode.form.transcript_file_delete',
),
@ -220,7 +219,7 @@
<div class="py-2 tab-panels">
<section id="chapters-file-upload" class="flex items-center tab-panel">
<?php if ($episode->chapters_file) : ?>
<div class="flex justify-between">
<div class="flex mb-1 gap-x-2">
<?= anchor(
$episode->chapters_file_url,
icon('file', 'mr-2') . $episode->chapters_file,
@ -239,9 +238,8 @@
icon('delete-bin', 'mx-auto'),
[
'class' =>
'p-1 bg-red-200 rounded-full text-red-700 hover:text-red-900',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'text-sm p-1 bg-red-100 rounded-full text-red-700 hover:text-red-900 focus:ring-accent',
'data-tooltip' => 'bottom',
'title' => lang(
'Episode.form.chapters_file_delete',
),

View File

@ -15,7 +15,7 @@
<?= $this->section('content') ?>
<p class="mb-4 text-sm italic text-gray-700">
<p class="mb-4 text-sm italic text-skin-muted">
<?= lang('Common.pageInfo', [
'currentPage' => $pager->getDetails()['currentPage'],
'pageCount' => $pager->getDetails()['pageCount'],
@ -45,12 +45,12 @@
episode_numbering(
$episode->number,
$episode->season_number,
'text-xs font-semibold text-gray-600 !no-underline border px-1 border-gray-500',
'text-xs font-semibold text-skin-muted !no-underline border px-1 border-gray-500',
true,
) .
'<span class="mr-1 truncate group-hover:underline">' . $episode->title . '</span>' .
'</h2>' .
'<p class="max-w-sm text-xs text-gray-600 line-clamp-2">' . $episode->description . '</p>' .
'<p class="max-w-sm text-xs text-skin-muted line-clamp-2">' . $episode->description . '</p>' .
'</a>' .
'</div>';
},
@ -73,7 +73,7 @@
[
'header' => lang('Episode.list.actions'),
'cell' => function ($episode, $podcast) {
return '<button id="more-dropdown-' . $episode->id . '" type="button" class="inline-flex items-center p-1 rounded-full focus:ring-castopod" data-dropdown="button" data-dropdown-target="more-dropdown-' . $episode->id . '-menu" aria-haspopup="true" aria-expanded="false">' .
return '<button id="more-dropdown-' . $episode->id . '" type="button" class="inline-flex items-center p-1 rounded-full focus:ring-accent" data-dropdown="button" data-dropdown-target="more-dropdown-' . $episode->id . '-menu" aria-haspopup="true" aria-expanded="false">' .
icon('more') .
'</button>' .
'<DropdownMenu id="more-dropdown-' . $episode->id . '-menu" labelledby="more-dropdown-' . $episode->id . '" offsetY="-24" items="' . esc(json_encode([

View File

@ -64,7 +64,7 @@
implode(
'',
array_map(function ($role) {
return '<span class="text-sm text-gray-600">' .
return '<span class="text-sm text-skin-muted">' .
lang(
"PersonsTaxonomy.persons.{$role->group}.label",
) .
@ -77,7 +77,7 @@
) .
($person->information_url === null
? ''
: "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"text-sm text-blue-800 hover:underline\">" .
: "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"font-semibold text-sm text-accent-base hover:text-accent-hover\">" .
$person->information_url .
'</a>') .
'</div></div>';

View File

@ -14,7 +14,7 @@
route_to('episode-view', $podcast->id, $episode->id),
icon('arrow-left', 'mr-2 text-lg') . lang('Episode.publish_form.back_to_episode_dashboard'),
[
'class' => 'inline-flex items-center font-semibold mr-4 text-sm focus:ring-castopod',
'class' => 'inline-flex items-center font-semibold mr-4 text-sm focus:ring-accent',
],
) ?>
@ -25,14 +25,14 @@
<label for="message" class="text-lg font-semibold"><?= lang(
'Episode.publish_form.post',
) ?></label>
<small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small>
<div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl">
<small class="max-w-md mb-2 text-skin-muted"><?= lang('Episode.publish_form.post_hint') ?></small>
<div class="mb-8 overflow-hidden shadow-md bg-elevated rounded-xl">
<div class="flex px-4 py-3 gap-x-2">
<img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full" />
<div class="flex flex-col min-w-0">
<p class="flex items-baseline min-w-0">
<span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $podcast->actor->username ?></span>
<span class="text-sm truncate text-skin-muted">@<?= $podcast->actor->username ?></span>
</p>
</div>
</div>
@ -49,11 +49,11 @@
<?= episode_numbering(
$episode->number,
$episode->season_number,
'text-xs font-semibold text-gray-600 !no-underline border px-1 border-gray-500',
'text-xs font-semibold text-skin-muted !no-underline border px-1 border-gray-500',
true,
) ?>
</div>
<div class="text-xs text-gray-600">
<div class="text-xs text-skin-muted">
<time datetime="PT<?= $episode->audio_file_duration ?>S">
<?= format_duration($episode->audio_file_duration) ?>
</time>
@ -63,9 +63,9 @@
</div>
</div>
<footer class="flex justify-around px-6 py-3">
<span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl opacity-40" />0</span>
<span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl opacity-40" />0</span>
<span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl opacity-40" />0</span>
</footer>
</div>
@ -76,7 +76,7 @@
<Forms.Radio value="now" name="publication_method" isChecked="<?= old('publication_method') ? old('publish') === 'now' : true ?>"><?= lang('Episode.publish_form.publication_method.now') ?></Forms.Radio>
<div class="inline-flex flex-wrap items-center radio-toggler">
<input
class="w-6 h-6 border-black text-pine-500 border-3 focus:ring-castopod"
class="w-6 h-6 border-contrast text-accent-base border-3 focus:ring-accent"
type="radio" id="schedule" name="publication_method" value="schedule" <?= old('publication_method') && old('publication_method') === 'schedule' ? 'checked' : '' ?> />
<Label for="schedule" class="pl-2 leading-8"><?= lang('Episode.publish_form.publication_method.schedule') ?></label>
<div class="w-full mt-2 radio-toggler-element">

View File

@ -26,16 +26,16 @@
<label for="message" class="text-lg font-semibold"><?= lang(
'Episode.publish_form.post',
) ?></label>
<small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small>
<div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl">
<small class="max-w-md mb-2 text-skin-muted"><?= lang('Episode.publish_form.post_hint') ?></small>
<div class="mb-8 overflow-hidden shadow-md bg-elevated rounded-xl">
<div class="flex px-4 py-3 gap-x-2">
<img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full" />
<div class="flex flex-col min-w-0">
<p class="flex items-baseline min-w-0">
<span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $podcast->actor->username ?></span>
<span class="text-sm truncate text-skin-muted">@<?= $podcast->actor->username ?></span>
</p>
<?= relative_time($post->published_at, 'text-xs text-gray-500') ?>
<?= relative_time($post->published_at, 'text-xs text-skin-muted') ?>
</div>
</div>
<div class="px-4 mb-2">
@ -51,11 +51,11 @@
<?= episode_numbering(
$episode->number,
$episode->season_number,
'text-xs font-semibold text-gray-600 !no-underline border px-1 border-gray-500',
'text-xs font-semibold text-skin-muted !no-underline border px-1 border-gray-500',
true,
) ?>
</div>
<div class="text-xs text-gray-600">
<div class="text-xs text-skin-muted">
<?= relative_time($episode->published_at) ?>
<span class="mx-1"></span>
<time datetime="PT<?= $episode->audio_file_duration ?>S">
@ -67,9 +67,9 @@
</div>
</div>
<footer class="flex justify-around px-6 py-3">
<span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl text-gray-400" />0</span>
<span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl opacity-40" />0</span>
<span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl opacity-40" />0</span>
<span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl opacity-40" />0</span>
</footer>
</div>
@ -80,7 +80,7 @@
<Forms.Radio value="now" name="publication_method" isChecked="<?= old('publication_method') && old('publish') === 'now' ?>"><?= lang('Episode.publish_form.publication_method.now') ?></Forms.Radio>
<div class="inline-flex flex-wrap items-center radio-toggler">
<input
class="w-6 h-6 border-black text-pine-500 border-3 focus:ring-castopod"
class="w-6 h-6 border-contrast text-accent-base border-3 focus:ring-accent"
type="radio" id="schedule" name="publication_method" value="schedule" <?= old('publication_method') ? old('publication_method') === 'schedule' : 'checked' ?> />
<Label for="schedule" class="pl-2 leading-8"><?= lang('Episode.publish_form.publication_method.schedule') ?></label>
<div class="w-full mt-2 radio-toggler-element">

View File

@ -22,7 +22,7 @@
'cell' => function ($page) {
return '<div class="flex flex-col">' .
$page->title .
'<span class="text-sm text-gray-600">/' .
'<span class="text-sm text-skin-muted">/' .
$page->slug .
'</span></div>';
},

View File

@ -1,4 +1,4 @@
<article class="relative h-full overflow-hidden transition bg-white shadow border-3 border-pine-100 rounded-xl group hover:shadow-xl focus-within:shadow-xl focus-within:ring-castopod">
<article class="relative h-full overflow-hidden transition shadow bg-elevated border-3 border-subtle rounded-xl group hover:shadow-xl focus-within:shadow-xl focus-within:ring-accent">
<a href="<?= route_to('person-view', $person->id) ?>" class="flex flex-col justify-end w-full h-full text-white group">
<div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient"></div>
<div class="w-full h-full overflow-hidden">
@ -8,7 +8,7 @@
<h2 class="px-4 py-2 font-semibold leading-tight"><?= $person->full_name ?></h2>
</div>
</a>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-castopod focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $person->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $person->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $person->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $person->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<DropdownMenu id="more-dropdown-<?= $person->id ?>-menu" labelledby="more-dropdown-<?= $person->id ?>" offsetY="-32" items="<?= esc(json_encode([
[
'type' => 'link',

View File

@ -15,19 +15,16 @@
<?= $this->section('content') ?>
<div class="flex flex-wrap">
<div class="w-full max-w-sm mb-6 md:mr-4">
<img
src="<?= $person->avatar->medium_url ?>"
alt="$person->full_name"
class="object-cover w-full rounded"
/>
<div class="flex flex-wrap gap-2">
<img
src="<?= $person->avatar->medium_url ?>"
alt="$person->full_name"
class="object-cover w-full max-w-xs rounded"
/>
<div class="flex flex-col">
<?= $person->full_name ?>
<a class="font-semibold no-underline text-accent-base hover:underline" href="<?= $person->information_url ?>"><?= $person->information_url ?></a>
</div>
<section class="w-full prose">
<?= $person->full_name ?><br />
<a href="<?= $person->information_url ?>"><?= $person->information_url ?></a>
</section>
</div>
<?= $this->endSection() ?>

View File

@ -1,4 +1,4 @@
<article class="relative h-full overflow-hidden transition bg-white shadow border-3 border-pine-100 group rounded-xl hover:shadow-xl focus-within:shadow-xl focus-within:ring-castopod">
<article class="relative h-full overflow-hidden transition shadow bg-elevated border-3 border-subtle group rounded-xl hover:shadow-xl focus-within:shadow-xl focus-within:ring-accent">
<a href="<?= route_to('podcast-view', $podcast->id) ?>" class="flex flex-col justify-end w-full h-full text-white group">
<div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient"></div>
<div class="w-full h-full overflow-hidden">
@ -11,7 +11,7 @@
<p class="text-sm transition duration-150 opacity-0 group-focus:opacity-75 group-hover:opacity-75">@<?= $podcast->handle ?></p>
</div>
</a>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-castopod focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $podcast->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $podcast->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $podcast->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $podcast->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
<DropdownMenu id="more-dropdown-<?= $podcast->id ?>-menu" labelledby="more-dropdown-<?= $podcast->id ?>" offsetY="-32" items="<?= esc(json_encode([
[
'type' => 'link',

View File

@ -35,7 +35,7 @@ $podcastNavigation = [
],
]; ?>
<div class="flex items-center px-4 py-2 border-b border-pine-900">
<div class="flex items-center px-4 py-2 border-b border-navigation">
<img
src="<?= $podcast->cover->thumbnail_url ?>"
alt="<?= $podcast->title ?>"
@ -46,8 +46,8 @@ $podcastNavigation = [
<a href="<?= route_to(
'podcast-activity',
$podcast->handle,
) ?>" class="inline-flex items-center text-sm hover:underline focus:ring-castopod"
data-toggle="tooltip" data-placement="bottom" title="<?= lang(
) ?>" class="inline-flex items-center text-sm hover:underline focus:ring-accent"
data-tooltip="bottom" title="<?= lang(
'PodcastNavigation.go_to_page',
) ?>">@<?= $podcast->handle ?>
<?= icon('external-link', 'ml-1 opacity-60') ?>
@ -57,7 +57,7 @@ $podcastNavigation = [
<nav class="flex flex-col flex-1 py-4 overflow-y-auto gap-y-4">
<?php foreach ($podcastNavigation as $section => $data): ?>
<div>
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-castopod" type="button">
<button class="inline-flex items-center w-full px-4 py-1 font-semibold focus:ring-accent" type="button">
<?= icon($data['icon'], 'opacity-60 text-2xl mr-4') .
lang('PodcastNavigation.' . $section) ?>
</button>
@ -65,7 +65,7 @@ $podcastNavigation = [
<?php foreach ($data['items'] as $item): ?>
<?php $isActive = url_is(route_to($item, $podcast->id)); ?>
<li class="inline-flex">
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-castopod <?= $isActive
<a class="w-full py-1 pl-14 pr-2 text-sm hover:opacity-100 focus:ring-inset focus:ring-accent <?= $isActive
? 'font-semibold opacity-100 inline-flex items-center'
: 'opacity-75' ?>" href="<?= route_to(
$item,

View File

@ -44,7 +44,7 @@
<div class="flex flex-col">
<Forms.Label for="handle" hint="<?= lang('Podcast.form.handle_hint') ?>"><?= lang('Podcast.form.handle') ?></Forms.Label>
<div class="relative">
<Icon glyph="at" class="absolute inset-0 h-full text-xl text-gray-400 left-3" />
<Icon glyph="at" class="absolute inset-0 h-full text-xl opacity-40 left-3" />
<Forms.Input name="handle" class="w-full pl-8" required="true" />
</div>
</div>
@ -166,7 +166,7 @@
label="<?= lang('Podcast.form.payment_pointer') ?>"
hint="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded">
<fieldset class="flex flex-col items-start p-4 rounded bg-base">
<Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
<div class="flex flex-col w-full clear-left gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-shrink w-32">

View File

@ -21,17 +21,17 @@
<form id="podcast-edit-form" action="<?= route_to('podcast-edit', $podcast->id) ?>" method="POST" enctype='multipart/form-data' class="flex flex-row-reverse flex-wrap items-start justify-end gap-4">
<?= csrf_field() ?>
<div class="sticky z-40 flex flex-col w-full max-w-xs overflow-hidden bg-white shadow-sm border-3 border-pine-100 top-24 rounded-xl">
<div class="sticky z-40 flex flex-col w-full max-w-xs overflow-hidden shadow-sm bg-elevated border-3 border-subtle top-24 rounded-xl">
<?php if ($podcast->banner_path !== null): ?>
<a href="<?= route_to('podcast-banner-delete', $podcast->id) ?>" class="absolute p-1 text-white bg-red-600 border-2 border-black rounded-full hover:bg-red-800 focus:ring-castopod top-2 right-2" title="<?= lang('Podcast.form.banner_delete') ?>"><?= icon('delete-bin') ?></a>
<a href="<?= route_to('podcast-banner-delete', $podcast->id) ?>" class="absolute p-1 text-red-700 bg-red-100 border-2 rounded-full hover:text-red-900 border-contrast focus:ring-accent top-2 right-2" title="<?= lang('Podcast.form.banner_delete') ?>" data-tooltip="bottom"><?= icon('delete-bin') ?></a>
<?php endif; ?>
<img src="<?= $podcast->banner->small_url ?>" alt="" class="object-cover w-full aspect-[3/1] bg-pine-800" />
<img src="<?= $podcast->banner->small_url ?>" alt="" class="object-cover w-full aspect-[3/1] bg-header" />
<div class="flex px-4 py-2">
<img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= $podcast->title ?>"
class="w-16 h-16 mr-4 -mt-8 rounded-full ring-2 ring-white" />
class="w-16 h-16 mr-4 -mt-8 rounded-full ring-2 ring-background-elevated" />
<div class="flex flex-col">
<p class="font-semibold leading-none"><?= $podcast->title ?></p>
<p class="text-sm text-gray-500">@<?= $podcast->handle ?></p>
<p class="text-sm text-skin-muted">@<?= $podcast->handle ?></p>
</div>
</div>
</div>
@ -189,7 +189,7 @@
value="<?= $podcast->payment_pointer ?>"
hint="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded">
<fieldset class="flex flex-col items-start p-4 rounded bg-base">
<Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
<div class="flex flex-col w-full clear-left gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-shrink w-32">

View File

@ -35,7 +35,7 @@
<div class="flex flex-col">
<Forms.Label for="handle" hint="<?= lang('Podcast.form.handle_hint') ?>"><?= lang('Podcast.form.handle') ?></Forms.Label>
<div class="relative">
<Icon glyph="at" class="absolute inset-0 h-full text-xl text-gray-400 left-3" />
<Icon glyph="at" class="absolute inset-0 h-full text-xl opacity-40 left-3" />
<Forms.Input name="handle" class="w-full pl-8" required="true" />
</div>
</div>

View File

@ -4,7 +4,7 @@
<a href="<?= route_to(
'episode-list',
$podcast->id,
) ?>" class="inline-flex items-center text-sm underline hover:no-underline focus:ring-castopod">
) ?>" class="inline-flex items-center text-sm underline hover:no-underline focus:ring-accent">
<?= lang('Podcast.see_all_episodes') ?>
<?= icon('chevron-right', 'ml-2') ?>
</a>

View File

@ -61,7 +61,7 @@
implode(
'',
array_map(function ($role) {
return '<span class="text-sm text-gray-600">' .
return '<span class="text-sm text-skin-muted">' .
lang(
"PersonsTaxonomy.persons.{$role->group}.label",
) .
@ -74,7 +74,7 @@
) .
($person->information_url === null
? ''
: "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"text-sm text-blue-800 hover:underline\">" .
: "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"font-semibold text-sm text-accent-base hover:text-accent-hover\">" .
$person->information_url .
'</a>') .
'</div></div>';

View File

@ -25,37 +25,34 @@
$platform->submit_url,
icon(
$platform->type . '/' . $platform->slug,
'text-gray-600 text-4xl',
'text-skin-muted text-4xl',
),
[
'class' => 'mb-1 text-gray-600 hover:text-gray-900',
'class' => 'mb-1 text-skin-muted hover:text-skin-base',
'target' => '_blank',
'rel' => 'noopener noreferrer',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
'title' => lang('Platforms.submit_url', [
'platformName' => $platform->label,
]),
],
) ?>
<div class="inline-flex bg-gray-200">
<div class="inline-flex bg-highlight">
<?= anchor($platform->home_url, icon('external-link', 'mx-auto'), [
'class' => 'flex-1 text-gray-600 hover:text-gray-900',
'class' => 'flex-1 text-skin-muted hover:text-skin-base',
'target' => '_blank',
'rel' => 'noopener noreferrer',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
'title' => lang('Platforms.home_url', [
'platformName' => $platform->label,
]),
]) ?>
<?= $platform->submit_url
? anchor($platform->submit_url, icon('add', 'mx-auto'), [
'class' => 'flex-1 text-gray-600 hover:text-gray-900',
'class' => 'flex-1 text-skin-muted hover:text-skin-base',
'target' => '_blank',
'rel' => 'noopener noreferrer',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
'title' => lang('Platforms.submit_url', [
'platformName' => $platform->label,
]),
@ -74,9 +71,8 @@
icon('delete-bin', 'mx-auto'),
[
'class' =>
'absolute right-0 p-1 bg-red-200 rounded-full text-red-700 hover:text-red-900',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'absolute right-0 p-1 bg-red-100 rounded-full text-red-700 hover:text-red-900',
'data-tooltip' => 'bottom',
'title' => lang('Platforms.remove', [
'platformName' => $platform->label,
]),

View File

@ -44,7 +44,7 @@
/>
<?php if (config('App')->siteIcon['ico'] !== service('settings')->get('App.siteIcon')['ico']): ?>
<div class="relative ml-2">
<a href="<?= route_to('settings-instance-delete-icon') ?>" class="absolute p-1 text-white bg-red-600 border-2 border-black rounded-full hover:bg-red-800 -top-3 -right-3 focus:ring-castopod" title="<?= lang('Settings.form.site_icon_delete') ?>"><?= icon('delete-bin') ?></a>
<a href="<?= route_to('settings-instance-delete-icon') ?>" class="absolute p-1 text-red-700 bg-red-100 border-2 rounded-full hover:text-red-900 border-contrast -top-3 -right-3 focus:ring-accent" title="<?= lang('Settings.form.site_icon_delete') ?>" data-tooltip="top"><?= icon('delete-bin') ?></a>
<img src="<?= service('settings')->get('App.siteIcon')['64'] ?>" alt="<?= service('settings')->get('App.siteName') ?> Favicon" class="w-10 h-10" />
</div>
<?php endif; ?>

View File

@ -22,7 +22,7 @@
'cell' => function ($user) {
return '<div class="flex flex-col">' .
$user->username .
'<span class="text-sm text-gray-600">' .
'<span class="text-sm text-skin-muted">' .
$user->email .
'</span></div>';
},
@ -47,7 +47,7 @@
[
'header' => lang('Common.actions'),
'cell' => function ($user) {
return '<button id="more-dropdown-' . $user->id . '" type="button" class="inline-flex items-center p-1 focus:ring-castopod" data-dropdown="button" data-dropdown-target="more-dropdown-' . $user->id . '-menu" aria-haspopup="true" aria-expanded="false">' . icon('more') . '</button>' .
return '<button id="more-dropdown-' . $user->id . '" type="button" class="inline-flex items-center p-1 focus:ring-accent" data-dropdown="button" data-dropdown-target="more-dropdown-' . $user->id . '-menu" aria-haspopup="true" aria-expanded="false">' . icon('more') . '</button>' .
'<DropdownMenu id="more-dropdown-' . $user->id . '-menu" labelledby="more-dropdown-' . $user->id . '" items="' . esc(json_encode([
[
'type' => 'link',

View File

@ -1,9 +1,9 @@
<div class="sticky top-0 left-0 z-50 flex items-center justify-between w-full h-10 text-white border-b bg-pine-800 border-pine-900">
<div class="sticky top-0 left-0 z-50 flex items-center justify-between w-full h-10 text-white border-b bg-navigation border-navigation">
<div class="inline-flex items-center h-full">
<a href="<?= route_to('home') ?>" class="inline-flex items-center h-full px-2 border-r border-pine-900 focus:ring-inset focus:ring-castopod">
<a href="<?= route_to('home') ?>" class="inline-flex items-center h-full px-2 border-r border-navigation focus:ring-inset focus:ring-accent">
<?= svg('castopod-logo-base', 'h-6') ?>
</a>
<a href="<?= route_to('admin', ) ?>" class="inline-flex items-center h-full px-6 text-sm font-semibold hover:underline focus:ring-inset focus:ring-castopod">
<a href="<?= route_to('admin', ) ?>" class="inline-flex items-center h-full px-6 text-sm font-semibold hover:underline focus:ring-inset focus:ring-accent">
<?= lang('AdminNavigation.go_to_admin') ?>
<?= icon('external-link', 'ml-1 opacity-60') ?>
</a>
@ -12,7 +12,7 @@
<div class="inline-flex items-center h-full">
<button
type="button"
class="inline-flex items-center h-full px-3 text-sm font-semibold focus:ring-inset focus:ring-castopod gap-x-2"
class="inline-flex items-center h-full px-3 text-sm font-semibold focus:ring-inset focus:ring-accent gap-x-2"
id="my-account-dropdown"
data-dropdown="button"
data-dropdown-target="my-account-dropdown-menu"
@ -20,17 +20,17 @@
aria-expanded="false"><div class="relative mr-1">
<?= icon('account-circle', 'text-3xl opacity-60') ?>
<?= user()
->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 border rounded-full -right-1 border-pine-800" />' ?>
->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 border rounded-full -right-1 border-navigation" />' ?>
</div>
<?= user()->username ?>
<?= icon('caret-down', 'ml-auto text-2xl') ?></button>
<?php
$interactButtons = '';
foreach (user()->podcasts as $userPodcast) {
$checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-pine-800 text-white rounded-full') : '';
$checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-accent-base text-accent-contrast rounded-full') : '';
$interactButtons .= <<<CODE_SAMPLE
<button class="inline-flex items-center w-full px-4 py-1 hover:bg-gray-100" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
<button class="inline-flex items-center w-full px-4 py-1 hover:bg-highlight" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
<span class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" />{$userPodcast->title}{$checkMark}</span>
</button>
CODE_SAMPLE;
@ -66,8 +66,8 @@
[
'type' => 'html',
'content' => esc(<<<CODE_SAMPLE
<nav class="flex flex-col py-2 text-black whitespace-no-wrap">
<span class="px-4 mb-2 text-xs font-semibold tracking-wider text-gray-500 uppercase">{$interactAsText}</span>
<nav class="flex flex-col py-2 whitespace-no-wrap">
<span class="px-4 mb-2 text-xs font-semibold tracking-wider uppercase text-skin-muted">{$interactAsText}</span>
<form action="{$route}" method="POST" class="flex flex-col">
{$csrfField}
{$interactButtons}

View File

@ -29,31 +29,31 @@
->asset('js/audio-player.ts', 'js') ?>
</head>
<body class="flex flex-col min-h-screen mx-auto bg-pine-50">
<body class="flex flex-col min-h-screen mx-auto bg-base">
<?php if (service('authentication')->check()): ?>
<?= $this->include('_admin_navbar') ?>
<?php endif; ?>
<header class="py-8 text-white border-b bg-pine-800">
<header class="py-8 text-white border-b bg-elevated border-subtle">
<div class="container flex flex-col items-start px-2 py-4 mx-auto">
<a href="<?= route_to('home') ?>"
class="inline-flex items-center mb-2 focus:ring-castopod"><?= icon(
class="inline-flex items-center mb-2 text-sm focus:ring-accent"><?= icon(
'arrow-left',
'mr-2',
) . lang('Page.back_to_home') ?></a>
<h1 class="text-3xl font-bold font-display"><?= isset($page)
<Heading tagName="h1" size="large"><?= isset($page)
? $page->title
: 'Castopod' ?></h1>
: 'Castopod' ?></Heading>
</div>
</header>
<main class="container flex-1 px-4 py-10 mx-auto">
<main class="container flex-1 px-4 py-6 mx-auto">
<?= $this->renderSection('content') ?>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t border-subtle">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="underline hover:no-underline focus:ring-castopod" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod</a>',
'<a class="underline hover:no-underline focus:ring-accent" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod</a>',
]) ?></small>
</footer>
</body>

View File

@ -1,12 +1,12 @@
<div id="persons-list" class="fixed top-0 left-0 z-50 flex items-center justify-center hidden w-screen h-screen">
<div
class="absolute w-full h-full bg-pine-800/75"
class="absolute w-full h-full bg-backdrop/75"
role="button"
data-toggle="persons-list"
data-toggle-class="hidden"
aria-label="<?= lang('Common.close') ?>"></div>
<div class="z-10 w-full max-w-xl bg-white rounded-lg shadow-2xl">
<div class="flex justify-between px-4 py-2 border-b">
<div class="z-10 w-full max-w-xl rounded-lg shadow-2xl bg-elevated">
<div class="flex justify-between px-4 py-2 border-b border-subtle">
<h3 class="self-center text-lg"><?= $title ?></h3>
<button
data-toggle="persons-list"
@ -21,12 +21,12 @@
<div class="flex flex-col">
<h4 class="text-sm font-semibold">
<?php if ($person->information_url): ?>
<a href="<?= $person->information_url ?>" class="hover:underline focus:ring-castopod" target="_blank" rel="noopener noreferrer"><?= $person->full_name ?></a>
<a href="<?= $person->information_url ?>" class="hover:underline focus:ring-accent" target="_blank" rel="noopener noreferrer"><?= $person->full_name ?></a>
<?php else: ?>
<?= $person->full_name ?>
<?php endif; ?>
</h4>
<p class="text-xs text-gray-500"><?= implode(
<p class="text-xs text-skin-muted"><?= implode(
', ',
array_map(function ($role) {
return lang(

View File

@ -9,23 +9,23 @@
<div class="grid w-full grid-cols-1 gap-4 md:grid-cols-2">
<?php foreach ($credits as $groupSlug => $groups): ?>
<?php if ($groupSlug): ?>
<div class="col-span-1 mt-12 mb-2 text-xl font-semibold text-gray-500 md:text-2xl md:col-span-2 "><?= $groups[
<h2 class="col-span-1 mt-12 mb-2 text-xl font-semibold text-skin-muted md:text-2xl md:col-span-2 "><?= $groups[
'group_label'
] ?></div>
] ?></h2>
<?php endif; ?>
<?php foreach ($groups['persons'] as $persons): ?>
<div class="flex mt-2 mb-2">
<img src="<?= $persons['thumbnail_url'] ?>" alt="<?= $persons[
'full_name'
] ?>" class="object-cover w-16 h-16 border-4 rounded-full md:h-24 md:w-24 border-gray" />
] ?>" class="object-cover w-16 h-16 rounded-full md:h-24 md:w-24 border-gray" />
<div class="flex flex-col ml-3 mr-4">
<span class="text-lg font-semibold text-gray-700 md:text-xl">
<span class="text-lg font-semibold text-skin-muted md:text-xl">
<?= $persons['full_name'] ?>
</span>
<?php if ($persons['information_url'] !== null): ?>
<a href="<?= $persons[
'information_url'
] ?>" class="text-sm text-blue-800 hover:underline" target="_blank" rel="noreferrer noopener"><?= $persons[
] ?>" class="text-sm font-semibold text-accent-base hover:underline" target="_blank" rel="noreferrer noopener"><?= $persons[
'information_url'
] ?></a>
<?php endif; ?>
@ -38,7 +38,7 @@
<?php foreach ($role['is_in'] as $in): ?>
<a href="<?= $in[
'link'
] ?>" class="text-sm text-gray-500 hover:underline"><?= $in[
] ?>" class="text-sm text-skin-muted hover:underline"><?= $in[
'title'
] ?></a>
<?php endforeach; ?>

View File

@ -38,7 +38,7 @@
language="<?= service('request')->getLocale() ?>"
icons="castopod-icons"
class="w-full mt-auto"
style="--vm-player-box-shadow:0; --vm-player-theme: #009486; --vm-control-spacing: 4px; --vm-control-icon-size: 24px; <?= str_ends_with($theme, 'transparent') ? '--vm-controls-bg: transparent;' : '' ?>"
style="--vm-player-box-shadow:0; --vm-player-theme: hsl(var(--color-accent-base)); --vm-control-focus-color: hsl(var(--color-accent-contrast)); --vm-control-spacing: 4px; --vm-menu-item-focus-bg: hsl(var(--color-background-highlight)); --vm-control-icon-size: 24px; <?= str_ends_with($theme, 'transparent') ? '--vm-controls-bg: transparent;' : '' ?>"
>
<vm-audio preload="none">
<?php $source = logged_in() ? $episode->audio_file_url : $episode->audio_file_analytics_url .

View File

@ -27,15 +27,15 @@
->asset('js/audio-player.ts', 'js') ?>
</head>
<body class="flex flex-col min-h-screen mx-auto md:min-h-full md:grid md:grid-cols-podcast bg-pine-50">
<body class="flex flex-col min-h-screen mx-auto md:min-h-full md:grid md:grid-cols-podcast bg-base">
<?php if (can_user_interact()): ?>
<div class="col-span-full">
<?= $this->include('_admin_navbar') ?>
</div>
<?php endif; ?>
<nav class="flex items-center justify-between h-10 col-start-2 text-white bg-pine-800">
<a href="<?= route_to('podcast-episodes', $podcast->handle) ?>" class="inline-flex items-center h-full px-2 focus:ring-castopod focus:ring-inset" title="<?= lang('Episode.back_to_episodes', [
<nav class="flex items-center justify-between h-10 col-start-2 text-white bg-header">
<a href="<?= route_to('podcast-episodes', $podcast->handle) ?>" class="inline-flex items-center h-full px-2 focus:ring-accent focus:ring-inset" title="<?= lang('Episode.back_to_episodes', [
'podcast' => $podcast->title,
]) ?>">
<?= icon('arrow-left', 'mr-2 text-lg') ?>
@ -51,38 +51,38 @@
</a>
<div class="inline-flex items-center self-end h-full px-2 gap-x-2">
<?php if (in_array(true, array_column($podcast->fundingPlatforms, 'is_visible'), true)): ?>
<IconButton glyph="heart" variant="accent" data-toggle="funding-links" data-toggle-class="hidden"><?= lang('Podcast.sponsor') . lang('Podcast.sponsor_title') ?></IconButton>
<button class="p-2 text-red-600 bg-white rounded-full shadow hover:text-red-500 focus:ring-accent" data-toggle="funding-links" data-toggle-class="hidden" title="<?= lang('Podcast.sponsor') ?>"><Icon glyph="heart"></Icon></button>
<?php endif; ?>
<?= anchor_popup(
route_to('follow', $podcast->handle),
icon(
'social/castopod',
'mr-2 text-xl text-rose-200 group-hover:text-rose-50',
'mr-2 text-xl text-black/75 group-hover:text-black',
) . lang('Podcast.follow'),
[
'width' => 420,
'height' => 620,
'class' =>
'group inline-flex items-center px-2 py-1 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:ring-castopod bg-rose-600',
'group inline-flex items-center px-3 leading-8 text-xs tracking-wider font-semibold text-black uppercase rounded-full shadow focus:ring-accent bg-white',
],
) ?>
</div>
</nav>
<header class="relative z-50 flex flex-col col-start-2 px-8 pt-8 pb-4 overflow-hidden bg-pine-500 gap-y-4">
<div class="absolute top-0 left-0 w-full h-full bg-center bg-no-repeat bg-cover blur-lg mix-blend-soft-light" style="background-image: url('<?= $episode->podcast->banner->small_url ?>');"></div>
<div class="absolute top-0 left-0 w-full h-full bg-gradient-to-t from-pine-800 to-transparent"></div>
<header class="relative z-50 flex flex-col col-start-2 px-8 pt-8 pb-4 overflow-hidden bg-accent-base/75 gap-y-4">
<div class="absolute top-0 left-0 w-full h-full bg-center bg-no-repeat bg-cover blur-lg mix-blend-overlay filter grayscale" style="background-image: url('<?= $episode->podcast->banner->small_url ?>');"></div>
<div class="absolute top-0 left-0 w-full h-full bg-gradient-to-t from-background-header to-transparent"></div>
<div class="z-10 flex flex-col items-start gap-y-2 gap-x-4 sm:flex-row">
<img src="<?= $episode->cover->medium_url ?>" alt="<?= $episode->title ?>" loading="lazy" class="rounded-md h-36" />
<img src="<?= $episode->cover->medium_url ?>" alt="<?= $episode->title ?>" loading="lazy" class="rounded-md shadow-xl h-36" />
<div class="flex flex-col items-start text-white">
<?= episode_numbering($episode->number, $episode->season_number, 'bg-pine-50 text-sm leading-none font-semibold text-gray-700 border !no-underline border-pine-100', true) ?>
<h1 class="inline-flex items-baseline max-w-md mt-2 text-2xl font-bold leading-none sm:text-3xl font-display line-clamp-2"><?= $episode->title ?></h1>
<?= episode_numbering($episode->number, $episode->season_number, 'text-sm leading-none font-semibold px-1 py-1 text-white/90 border !no-underline border-subtle', true) ?>
<h1 class="inline-flex items-baseline max-w-md mt-2 text-2xl font-bold sm:leading-none sm:text-3xl font-display line-clamp-2"><?= $episode->title ?></h1>
<div class="flex items-center mt-4 gap-x-8">
<?php if ($episode->persons !== []): ?>
<button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-castopod" data-toggle="persons-list" data-toggle-class="hidden">
<button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
<div class="inline-flex flex-row-reverse">
<?php $i = 0; ?>
<?php foreach ($episode->persons as $person): ?>
<img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 h-8 -ml-5 border-2 rounded-full border-pine-100 last:ml-0" />
<img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 h-8 -ml-5 border-2 rounded-full border-background-header last:ml-0" />
<?php $i++; if ($i === 3) {
break;
}?>
@ -118,12 +118,12 @@
</div>
</div>
</header>
<div class="col-start-2 px-8 py-4 text-white bg-pine-800">
<div class="col-start-2 px-8 py-4 text-white bg-header">
<h2 class="text-xs font-bold tracking-wider uppercase whitespace-pre-line font-display"><?= lang('Episode.description') ?></h2>
<?php if (substr_count($episode->description_markdown, "\n") > 3 || strlen($episode->description) > 250): ?>
<SeeMore class="max-w-xl prose-sm text-white whitespace-pre-line"><?= $episode->getDescriptionHtml('-+Website+-') ?></SeeMore>
<SeeMore class="max-w-xl prose-sm text-white"><?= $episode->getDescriptionHtml('-+Website+-') ?></SeeMore>
<?php else: ?>
<div class="max-w-xl prose-sm text-white whitespace-pre-line"><?= $episode->getDescriptionHtml('-+Website+-') ?></div>
<div class="max-w-xl prose-sm text-white"><?= $episode->getDescriptionHtml('-+Website+-') ?></div>
<?php endif; ?>
</div>
<?= $this->include('episode/_partials/navigation') ?>
@ -131,7 +131,7 @@
<main class="w-full col-start-1 row-start-1 py-6 col-span-full md:col-span-1">
<?= $this->renderSection('content') ?>
</main>
<div data-sidebar-toggler="backdrop" class="absolute top-0 left-0 z-10 hidden w-full h-full bg-pine-800/75 md:hidden" role="button" tabIndex="0" aria-label="Close"></div>
<div data-sidebar-toggler="backdrop" class="absolute top-0 left-0 z-10 hidden w-full h-full bg-backdrop/75 md:hidden" role="button" tabIndex="0" aria-label="Close"></div>
<?= $this->include('podcast/_partials/sidebar') ?>
</div>
<?= view('_persons_modal', [

View File

@ -1,6 +1,6 @@
<article class="flex w-full p-4 bg-white shadow rounded-conditional-2xl gap-x-2">
<article class="flex w-full p-4 shadow bg-elevated rounded-conditional-2xl gap-x-2">
<div class="relative">
<time class="absolute px-1 text-xs font-semibold text-white rounded bottom-2 right-2 bg-black/50" datetime="PT<?= $episode->audio_file_duration ?>S">
<time class="absolute px-1 text-xs font-semibold text-white rounded bottom-2 right-2 bg-black/75" datetime="PT<?= $episode->audio_file_duration ?>S">
<?= format_duration($episode->audio_file_duration) ?>
</time>
<img loading="lazy" src="<?= $episode->cover
@ -9,8 +9,8 @@
<div class="flex items-center flex-1 gap-x-4">
<div class="flex flex-col flex-1">
<div class="inline-flex items-center">
<?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold text-gray-700 px-1 border mr-2 !no-underline', true) ?>
<?= relative_time($episode->published_at, 'text-xs whitespace-nowrap') ?>
<?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold border-subtle text-skin-muted px-1 border mr-2 !no-underline', true) ?>
<?= relative_time($episode->published_at, 'text-xs whitespace-nowrap text-skin-muted') ?>
</div>
<h2 class="flex-1 font-semibold line-clamp-2"><a class="hover:underline" href="<?= $episode->link ?>"><?= $episode->title ?></a></h2>
</div>

View File

@ -8,12 +8,12 @@
: 'target="_blank" rel="noopener noreferrer"' ?>>
<span class="mr-2 font-semibold truncate"><?= $comment->actor
->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $comment->actor
<span class="text-sm text-skin-muted truncate">@<?= $comment->actor
->username .
($comment->actor->is_local
? ''
: '@' . $comment->actor->domain) ?></span>
<?= relative_time($comment->created_at, 'text-xs text-gray-500 ml-auto flex-shrink-0') ?>
<?= relative_time($comment->created_at, 'text-xs text-skin-muted ml-auto flex-shrink-0') ?>
</a>
</header>
<div class="mb-2 post-content"><?= $comment->message_html ?></div>

View File

@ -6,7 +6,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . $comment->likes_count ?></button>
<Button uri="<?= route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
</form>
<?php if ($comment->replies_count): ?>
@ -26,7 +26,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-500') . $comment->likes_count ?></button>
) ?>"><?= icon('heart', 'text-xl mr-1 text-skin-muted') . $comment->likes_count ?></button>
<?php if ($comment->replies_count): ?>
<?= anchor(
route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id),

View File

@ -6,7 +6,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . $comment->likes_count ?></button>
<Button uri="<?= route_to('post', $podcast->handle, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
</form>
<?php if ($comment->replies_count): ?>
@ -26,7 +26,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-500') . $comment->likes_count ?></button>
) ?>"><?= icon('heart', 'text-xl mr-1 text-skin-muted') . $comment->likes_count ?></button>
<?php if ($comment->replies_count): ?>
<?= anchor(
route_to('post', $podcast->handle, $comment->id),

View File

@ -1,4 +1,4 @@
<article class="relative z-10 flex w-full p-4 bg-white shadow rounded-conditional-2xl gap-x-2">
<article class="relative z-10 flex w-full p-4 shadow bg-elevated rounded-conditional-2xl gap-x-2">
<img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 rounded-full" />
<div class="flex-1">
<header class="w-full mb-2 text-sm">
@ -7,12 +7,12 @@
: 'target="_blank" rel="noopener noreferrer"' ?>>
<span class="mr-2 font-semibold truncate"><?= $comment->actor
->display_name ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $comment->actor
<span class="text-sm truncate text-skin-muted">@<?= $comment->actor
->username .
($comment->actor->is_local
? ''
: '@' . $comment->actor->domain) ?></span>
<?= relative_time($comment->created_at, 'text-xs text-gray-500 ml-auto') ?>
<?= relative_time($comment->created_at, 'text-xs text-skin-muted ml-auto') ?>
</a>
</header>
<div class="mb-2 post-content"><?= $comment->message_html ?></div>
@ -27,7 +27,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . lang(
) ?>"><?= icon('heart', 'text-xl mr-1 opacity-40 group-hover:text-red-600 group-hover:opacity-100') . lang(
'Comment.likes',
[
'numberOfLikes' => $comment->likes_count,
@ -40,7 +40,7 @@
[
'numberOfLikes' => $comment->likes_count,
],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-500') . lang(
) ?>"><?= icon('heart', 'text-xl mr-1 text-skin-muted') . lang(
'Comment.likes',
[
'numberOfLikes' => $comment->likes_count,

View File

@ -1,4 +1,4 @@
<article class="flex px-6 py-4 bg-gray-50 gap-x-2">
<article class="flex px-6 py-4 bg-base gap-x-2">
<img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor
->display_name ?>" class="z-10 w-10 h-10 rounded-full ring-gray-50 ring-2" />
<div class="flex flex-col flex-1 min-w-0">
@ -8,10 +8,10 @@
->actor->is_local
? ''
: 'target="_blank" rel="noopener noreferrer"' ?>><?= $reply->actor
->display_name ?><span class="ml-1 text-sm font-normal text-gray-600">@<?= $reply
->display_name ?><span class="ml-1 text-sm font-normal text-skin-muted">@<?= $reply
->actor->username .
($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
<?= relative_time($reply->created_at, 'flex-shrink-0 ml-auto text-xs text-gray-600') ?>
<?= relative_time($reply->created_at, 'flex-shrink-0 ml-auto text-xs text-skin-muted') ?>
</header>
<p class="mb-2 post-content"><?= $reply->message_html ?></p>
<?= $this->include('episode/_partials/comment_reply_actions') ?>

View File

@ -6,7 +6,7 @@
[
'numberOfLikes' => $reply->likes_count,
],
) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button>
) ?>"><?= icon('heart', 'text-lg mr-1 opacity-40 group-hover:text-red-600') . $reply->likes_count ?></button>
<Button uri="<?= route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
</form>
<?php else: ?>
@ -15,11 +15,11 @@
[
'numberOfLikes' => $reply->likes_count,
],
) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-500') . $reply->likes_count ?></button>
) ?>"><?= icon('heart', 'text-lg mr-1 text-skin-muted') . $reply->likes_count ?></button>
<?php if ($reply->replies_count): ?>
<?= anchor(
route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id),
icon('chat', 'text-2xl mr-1 text-gray-400') . $reply->replies_count,
icon('chat', 'text-2xl mr-1 opacity-40') . $reply->replies_count,
[
'class' => 'inline-flex items-center hover:underline',
'title' => lang('Comment.replies', [

View File

@ -1,21 +1,21 @@
<?php declare(strict_types=1);
if ($comment->in_reply_to_id): ?>
<div class="relative -mb-2 overflow-hidden border-t border-l border-r rounded-t-xl">
<div class="absolute z-0 w-[2px] h-full bg-gray-300 left-[43px] top-4"></div>
<div class="relative -mb-2 overflow-hidden border-t border-l border-r border-subtle rounded-t-xl">
<div class="absolute z-0 w-[2px] h-full bg-base left-[43px] top-4"></div>
<?= view('episode/_partials/comment_reply', [
'reply' => $comment->reply_to_comment,
]) ?>
</div>
<?php endif; ?>
<?= $this->include('episode/_partials/comment_card') ?>
<div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl">
<div class="-mt-2 overflow-hidden border-b border-l border-r border-subtle post-replies rounded-b-xl">
<?php if (can_user_interact()): ?>
<form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 gap-x-2 bg-gray-50">
<form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 gap-x-2 bg-base">
<img src="<?= interact_as_actor()
->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-10 h-10 rounded-full ring-gray-50 ring-2" />
->display_name ?>" class="w-10 h-10 rounded-full" />
<div class="flex flex-col flex-1">
<Forms.Textarea
name="message"
@ -31,7 +31,7 @@ if ($comment->in_reply_to_id): ?>
<?php endif; ?>
<?php if ($comment->has_replies): ?>
<div class="border-t divide-y">
<div class="border-t divide-y border-subtle">
<?php foreach ($comment->replies as $reply): ?>
<?= view('episode/_partials/comment_reply', [
'reply' => $reply,

View File

@ -13,10 +13,10 @@ $navigationItems = [
],
]
?>
<nav class="sticky z-40 flex col-start-2 px-4 pt-4 bg-white shadow md:px-8 gap-x-2 md:gap-x-4 -top-4 rounded-conditional-b-xl">
<nav class="sticky z-40 flex col-start-2 pt-4 shadow bg-elevated md:px-8 gap-x-2 md:gap-x-4 -top-4 rounded-conditional-b-xl">
<?php foreach ($navigationItems as $item): ?>
<?php $isActive = url_is($item['uri']); ?>
<a href="<?= $item['uri'] ?>" class="px-4 py-1 text-sm font-semibold uppercase focus:ring-castopod border-b-4<?= $isActive ? ' border-b-4 text-pine-500 border-pine-500' : ' text-gray-500 hover:text-gray-900 hover:border-gray-200 border-transparent' ?>"><?= $item['label'] ?><span class="px-2 ml-1 font-semibold rounded-full <?= $isActive ? ' bg-pine-100' : ' bg-gray-100' ?>"><?= $item['labelInfo'] ?></span></a>
<a href="<?= $item['uri'] ?>" class="px-4 py-1 text-sm font-semibold uppercase focus:ring-accent border-b-4<?= $isActive ? ' border-b-4 text-accent-base border-accent-base' : ' text-skin-muted hover:text-skin-base hover:border-subtle border-transparent' ?>"><?= $item['label'] ?><span class="px-2 ml-1 font-semibold rounded-full bg-base"><?= $item['labelInfo'] ?></span></a>
<?php endforeach; ?>
<button type="button" class="p-2 ml-auto rotate-180 rounded-full md:hidden focus:ring-castopod" data-sidebar-toggler="toggler"><?= icon('menu') ?></button>
<button type="button" class="p-2 ml-auto rotate-180 rounded-full md:hidden focus:ring-accent" data-sidebar-toggler="toggler"><?= icon('menu') ?></button>
</nav>

View File

@ -1,6 +1,6 @@
<div class="flex items-center border-t border-b">
<div class="flex items-center border-t border-b border-subtle">
<div class="relative">
<time class="absolute px-1 text-sm font-semibold text-white bg-black/50 bottom-2 right-2" datetime="PT<?= $episode->audio_file_duration ?>S">
<time class="absolute px-1 text-sm font-semibold text-white rounded bg-black/75 bottom-2 right-2" datetime="PT<?= $episode->audio_file_duration ?>S">
<?= format_duration($episode->audio_file_duration) ?>
</time>
<img
@ -9,8 +9,8 @@
</div>
<div class="flex flex-col flex-1 px-4 py-2">
<div class="inline-flex">
<?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold text-gray-700 px-1 border mr-2 !no-underline', true) ?>
<?= relative_time($episode->published_at, 'text-xs whitespace-nowrap text-gray-500') ?>
<?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold text-skin-muted px-1 border border-subtle mr-2 !no-underline', true) ?>
<?= relative_time($episode->published_at, 'text-xs whitespace-nowrap text-skin-muted') ?>
</div>
<a href="<?= $episode->link ?>" class="flex items-baseline font-semibold line-clamp-2" title="<?= $episode->title ?>"><?= $episode->title ?></a>
</div>

View File

@ -35,7 +35,7 @@
<?php if (can_user_interact()): ?>
<?= view('_message_block') ?>
<form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 bg-white shadow gap-x-2 rounded-conditional-2xl">
<form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
<?= csrf_field() ?>
<img src="<?= interact_as_actor()
@ -51,7 +51,7 @@
<Button variant="primary" size="small" type="submit" class="self-end" iconRight="send-plane"><?= lang('Post.form.submit') ?></Button>
</div>
</form>
<hr class="my-4 border-2 border-pine-100">
<hr class="my-4 border-subtle">
<?php endif; ?>
<div class="flex flex-col gap-y-4">

View File

@ -21,7 +21,7 @@
<div class="max-w-2xl px-6 mx-auto">
<nav class="mb-2">
<a href="<?= route_to('episode', $podcast->handle, $episode->slug) ?>"
class="inline-flex items-center px-4 py-2 text-sm focus:ring-castopod"><?= icon(
class="inline-flex items-center px-4 py-2 text-sm focus:ring-accent"><?= icon(
'arrow-left',
'mr-2 text-lg',
) . lang('Comment.back_to_comments') ?></a>

View File

@ -28,12 +28,12 @@
->asset('js/app.ts', 'js') ?>
</head>
<body class="flex flex-col min-h-screen mx-auto bg-pine-50">
<body class="flex flex-col min-h-screen mx-auto bg-base">
<?php if (service('authentication')->check()): ?>
<?= $this->include('_admin_navbar') ?>
<?php endif; ?>
<header class="py-8 text-white border-b bg-pine-800">
<header class="py-8 text-white border-b bg-header border-subtle">
<div class="container flex items-center justify-between px-2 py-4 mx-auto">
<a href="<?= route_to(
'home',
@ -42,13 +42,13 @@
</div>
</header>
<main class="container flex-1 px-4 py-10 mx-auto">
<h1 class="mb-2 text-xl"><?= lang('Home.all_podcasts') ?> (<?= count(
<Heading class="inline-block mb-2"><?= lang('Home.all_podcasts') ?> (<?= count(
$podcasts,
) ?>)</h1>
) ?>)</Heading>
<section class="grid gap-4 grid-cols-cards">
<?php if ($podcasts): ?>
<?php foreach ($podcasts as $podcast): ?>
<a href="<?= $podcast->link ?>" class="relative w-full h-full overflow-hidden transition shadow focus:ring-castopod rounded-xl border-pine-100 hover:shadow-xl focus:shadow-xl group border-3">
<a href="<?= $podcast->link ?>" class="relative w-full h-full overflow-hidden transition shadow focus:ring-accent rounded-xl border-subtle hover:shadow-xl focus:shadow-xl group border-3">
<article class="text-white">
<div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient"></div>
<div class="w-full h-full overflow-hidden">
@ -66,11 +66,11 @@
<?php endif; ?>
</section>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t border-subtle">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="inline-flex font-semibold hover:underline focus:ring-castopod" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
'<a class="inline-flex font-semibold hover:underline focus:ring-accent" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
]) ?></small>
</footer>
</body>

View File

@ -20,29 +20,29 @@
->asset('js/map.ts', 'js') ?>
</head>
<body class="flex flex-col h-full min-h-screen mx-auto bg-gray-100">
<body class="flex flex-col h-full min-h-screen mx-auto bg-base">
<?php if (service('authentication')->check()): ?>
<?= $this->include('_admin_navbar') ?>
<?php endif; ?>
<header class="py-8 text-white border-b bg-pine-800">
<header class="py-8 text-white border-b border-subtle bg-elevated">
<div class="container flex flex-col items-start px-2 py-4 mx-auto">
<a href="<?= route_to('home') ?>"
class="inline-flex items-center mb-2 focus:ring-castopod"><?= icon(
class="inline-flex items-center mb-2 text-sm focus:ring-accent"><?= icon(
'arrow-left',
'mr-2',
) . lang('Page.back_to_home') ?></a>
<h1 class="text-3xl font-semibold"><?= lang('Page.map') ?></h1>
<Heading tagName="h1" size="large"><?= lang('Page.map') ?></Heading>
</div>
</header>
<main class="flex-1 w-full h-full">
<div id="map" data-episodes-map-data-url="<?= url_to('episodes-markers') ?>" class="w-full h-full"></div>
<div id="map" data-episodes-map-data-url="<?= url_to('episodes-markers') ?>" class="z-10 w-full h-full"></div>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="inline-flex font-semibold hover:underline focus:ring-castopod" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
'<a class="inline-flex font-semibold hover:underline focus:ring-accent" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
]) ?></small>
</footer>
</body>

View File

@ -17,15 +17,15 @@
->asset('js/app.ts', 'js') ?>
</head>
<body class="flex flex-col min-h-screen mx-auto">
<body class="flex flex-col min-h-screen mx-auto bg-base">
<?php if (service('authentication')->check()): ?>
<?= $this->include('_admin_navbar') ?>
<?php endif; ?>
<header class="py-8 text-white border-b bg-pine-800">
<header class="py-8 border-b bg-elevated border-subtle">
<div class="container flex flex-col items-start px-2 py-4 mx-auto">
<a href="<?= route_to('home') ?>"
class="inline-flex items-center mb-2 focus:ring-castopod"><?= icon(
class="inline-flex items-center mb-2 focus:ring-accent"><?= icon(
'arrow-left',
'mr-2',
) . lang('Page.back_to_home') ?></a>
@ -33,15 +33,15 @@
</div>
</header>
<main class="container flex-1 px-4 py-10 mx-auto">
<div class="prose">
<div class="prose prose-brand">
<?= $page->content_html ?>
</div>
</main>
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t">
<footer class="container flex justify-between px-2 py-4 mx-auto text-sm text-right border-t border-subtle">
<?= render_page_links() ?>
<small><?= lang('Common.powered_by', [
'castopod' =>
'<a class="inline-flex font-semibold hover:underline focus:ring-castopod" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
'<a class="inline-flex font-semibold hover:underline focus:ring-accent" href="https://castopod.org/" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
]) ?></small>
</footer>
</body>

View File

@ -27,18 +27,18 @@
->asset('js/audio-player.ts', 'js') ?>
</head>
<body class="flex flex-col min-h-screen mx-auto md:min-h-full md:grid md:grid-cols-podcast bg-pine-50">
<body class="flex flex-col min-h-screen mx-auto md:min-h-full md:grid md:grid-cols-podcast bg-base">
<?php if (can_user_interact()): ?>
<div class="col-span-full">
<?= $this->include('_admin_navbar') ?>
</div>
<?php endif; ?>
<header class="relative z-50 flex flex-col-reverse justify-between w-full col-start-2 bg-top bg-no-repeat bg-cover sm:flex-row sm:items-end bg-pine-800 aspect-[3/1]" style="background-image: url('<?= $podcast->banner->medium_url ?>');">
<div class="absolute bottom-0 left-0 w-full h-full backdrop-gradient-pine"></div>
<header class="relative z-50 flex flex-col-reverse justify-between w-full col-start-2 bg-top bg-no-repeat bg-cover sm:flex-row sm:items-end bg-header aspect-[3/1]" style="background-image: url('<?= $podcast->banner->medium_url ?>');">
<div class="absolute bottom-0 left-0 w-full h-full backdrop-gradient"></div>
<div class="z-10 flex items-center pl-4 -mb-6 md:pl-8 md:-mb-8 gap-x-4">
<img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= $podcast->title ?>" loading="lazy" class="h-24 rounded-full md:h-28 ring-4 ring-white" />
<div class="relative flex flex-col text-white -top-2">
<img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= $podcast->title ?>" loading="lazy" class="h-24 rounded-full sm:h-28 md:h-36 ring-3 ring-background-elevated" />
<div class="relative flex flex-col text-white -top-2 sm:top-0 md:top-2">
<h1 class="text-lg font-bold leading-none line-clamp-2 md:leading-none md:text-2xl font-display"><?= $podcast->title ?><span class="ml-1 font-sans text-base font-normal">@<?= $podcast->handle ?></span></h1>
<span class="text-xs"><?= lang('Podcast.followers', [
'numberOfFollowers' => $podcast->actor->followers_count,
@ -47,19 +47,19 @@
</div>
<div class="z-10 inline-flex items-center self-end mt-2 mr-2 sm:mb-4 sm:mr-4 gap-x-2">
<?php if (in_array(true, array_column($podcast->fundingPlatforms, 'is_visible'), true)): ?>
<IconButton glyph="heart" variant="accent" data-toggle="funding-links" data-toggle-class="hidden"><?= lang('Podcast.sponsor') . lang('Podcast.sponsor_title') ?></IconButton>
<button class="p-2 text-red-600 bg-white rounded-full shadow hover:text-red-500 focus:ring-accent" data-toggle="funding-links" data-toggle-class="hidden" data-tooltip="bottom" title="<?= lang('Podcast.sponsor') ?>"><Icon glyph="heart"></Icon></button>
<?php endif; ?>
<?= anchor_popup(
route_to('follow', $podcast->handle),
icon(
'social/castopod',
'mr-2 text-xl text-rose-200 group-hover:text-rose-50',
'mr-2 text-xl text-black/75 group-hover:text-black',
) . lang('Podcast.follow'),
[
'width' => 420,
'height' => 620,
'class' =>
'group inline-flex items-center px-2 py-1 text-xs tracking-wider font-semibold text-white uppercase rounded-full shadow focus:ring-castopod bg-rose-600',
'group inline-flex items-center px-4 text-xs tracking-wider font-semibold text-black uppercase rounded-full leading-8 shadow focus:ring-accent bg-white',
],
) ?>
</div>

View File

@ -1,12 +1,12 @@
<div id="funding-links" class="fixed top-0 left-0 z-50 flex items-center justify-center hidden w-screen h-screen">
<div
class="absolute w-full h-full bg-pine-800/75"
class="absolute w-full h-full bg-backdrop/75"
role="button"
data-toggle="funding-links"
data-toggle-class="hidden"
aria-label="<?= lang('Common.close') ?>"></div>
<div class="z-10 w-full max-w-xl bg-white rounded-lg shadow-2xl">
<div class="flex justify-between px-4 py-2 border-b">
<div class="z-10 w-full max-w-xl rounded-lg shadow-2xl bg-elevated">
<div class="flex justify-between px-4 py-2 border-b border-subtle">
<h3 class="self-center text-lg"><?= lang('Podcast.funding_links', [
'podcastTitle' => $podcast->title,
]) ?></h3>
@ -24,7 +24,7 @@
title="<?= $fundingPlatform->link_content ?>"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center font-semibold text-pine-900">
class="inline-flex items-center font-semibold text-accent-base">
<?= icon(
$fundingPlatform->type .
'/' .

View File

@ -15,10 +15,10 @@ $navigationItems = [
],
]
?>
<nav class="sticky z-40 flex col-start-2 px-2 pt-8 bg-white shadow gap-x-2 md:gap-x-4 md:px-8 -top-6 md:-top-10 rounded-conditional-b-xl md:pt-12 ">
<nav class="sticky z-40 flex col-start-2 pt-8 shadow bg-elevated gap-x-2 md:gap-x-4 md:px-8 -top-6 md:-top-10 rounded-conditional-b-xl md:pt-12 ">
<?php foreach ($navigationItems as $item): ?>
<?php $isActive = url_is($item['uri']); ?>
<a href="<?= $item['uri'] ?>" class="px-4 py-1 text-sm font-semibold uppercase focus:ring-castopod border-b-4<?= $isActive ? ' border-b-4 text-pine-500 border-pine-500' : ' text-gray-500 hover:text-gray-900 hover:border-gray-200 border-transparent' ?>"><?= $item['label'] ?></a>
<a href="<?= $item['uri'] ?>" class="px-4 py-1 text-sm font-semibold uppercase focus:ring-accent border-b-4<?= $isActive ? ' border-b-4 text-accent-base border-accent-base' : ' text-skin-muted hover:text-skin-base hover:border-subtle border-transparent' ?>"><?= $item['label'] ?></a>
<?php endforeach; ?>
<button type="button" class="p-2 ml-auto rotate-180 rounded-full md:hidden focus:ring-castopod" data-sidebar-toggler="toggler"><?= icon('menu') ?></button>
<button type="button" class="p-2 ml-auto rotate-180 rounded-full md:hidden focus:ring-accent" data-sidebar-toggler="toggler"><?= icon('menu') ?></button>
</nav>

View File

@ -1,13 +1,13 @@
<div data-sidebar-toggler="backdrop" class="absolute top-0 left-0 z-10 hidden w-full h-full bg-pine-800/75 md:hidden" role="button" tabIndex="0" aria-label="Close"></div>
<aside id="podcast-sidebar" data-sidebar-toggler="sidebar" data-toggle-class="hidden" data-hide-class="hidden" class="z-20 hidden h-full col-span-1 col-start-2 row-start-1 p-4 py-6 shadow-2xl md:shadow-none md:block bg-pine-50">
<div class="sticky z-10 bg-pine-50 top-12">
<a href="<?= route_to('podcast_feed', $podcast->handle) ?>" class="inline-flex items-center mb-6 text-sm font-semibold focus:ring-castopod text-pine-800 group" target="_blank" rel="noopener noreferrer">
<div data-sidebar-toggler="backdrop" class="absolute top-0 left-0 z-10 hidden w-full h-full bg-backdrop/75 md:hidden" role="button" tabIndex="0" aria-label="Close"></div>
<aside id="podcast-sidebar" data-sidebar-toggler="sidebar" data-toggle-class="hidden" data-hide-class="hidden" class="z-20 hidden h-full col-span-1 col-start-2 row-start-1 p-4 py-6 shadow-2xl md:shadow-none md:block bg-base">
<div class="sticky z-10 bg-base top-12">
<a href="<?= route_to('podcast_feed', $podcast->handle) ?>" class="inline-flex items-center mb-6 text-sm font-semibold focus:ring-accent text-skin-muted hover:text-skin-base group" target="_blank" rel="noopener noreferrer">
<?= icon('rss', ' mr-2 bg-orange-500 text-xl text-white group-hover:bg-orange-700 p-1 w-6 h-6 inline-flex items-center justify-center rounded-lg') . lang('Podcast.feed') ?>
</a>
<?php if (
in_array(true, array_column($podcast->socialPlatforms, 'is_visible'), true)
): ?>
<h2 class="mb-2 font-bold font-display text-pine-900"> <?= lang('Podcast.find_on', [
<h2 class="text-sm font-bold font-display text-accent-muted"> <?= lang('Podcast.find_on', [
'podcastTitle' => $podcast->title,
]) ?></h2>
<div class="grid items-center justify-center grid-cols-6 gap-3 mb-6">
@ -17,11 +17,10 @@
$socialPlatform->link_url,
icon("{$socialPlatform->type}/{$socialPlatform->slug}"),
[
'class' => 'text-2xl text-gray-500 hover:text-gray-700 w-8 h-8 items-center inline-flex justify-center',
'class' => 'text-2xl text-skin-muted hover:text-skin-base w-8 h-8 items-center inline-flex justify-center',
'target' => '_blank',
'rel' => 'noopener noreferrer',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
'title' => $socialPlatform->label,
],
) ?>
@ -33,7 +32,7 @@
<?php if (
in_array(true, array_column($podcast->podcastingPlatforms, 'is_visible'), true)
): ?>
<h2 class="mb-2 font-bold font-display text-pine-900"><?= lang('Podcast.listen_on') ?></h2>
<h2 class="text-sm font-bold font-display text-accent-muted"><?= lang('Podcast.listen_on') ?></h2>
<div class="grid items-center justify-center grid-cols-6 gap-3 mb-6">
<?php foreach ($podcast->podcastingPlatforms as $podcastingPlatform): ?>
<?php if ($podcastingPlatform->is_visible): ?>
@ -43,11 +42,10 @@
"{$podcastingPlatform->type}/{$podcastingPlatform->slug}",
),
[
'class' => 'text-2xl text-gray-500 hover:text-gray-700 w-8 h-8 items-center inline-flex justify-center',
'class' => 'text-2xl text-skin-muted hover:text-skin-base w-8 h-8 items-center inline-flex justify-center',
'target' => '_blank',
'rel' => 'noopener noreferrer',
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
'data-tooltip' => 'bottom',
'title' => $podcastingPlatform->label,
],
) ?>
@ -55,13 +53,13 @@
<?php endforeach; ?>
</div>
<?php endif; ?>
<footer class="flex flex-col items-center py-2 text-xs text-center text-gray-600 border-t">
<?= render_page_links('inline-flex mb-2 flex-wrap gap-y-1') ?>
<footer class="flex flex-col items-center py-2 text-xs text-center border-t border-subtle text-skin-muted">
<?= render_page_links('inline-flex mb-2 flex-wrap gap-y-1 justify-center') ?>
<div class="flex flex-col">
<p><?= $podcast->copyright ?></p>
<p><?= lang('Common.powered_by', [
'castopod' =>
'<a class="inline-flex font-semibold text-gray-500 hover:underline focus:ring-castopod" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
'<a class="inline-flex font-semibold text-skin-muted hover:underline focus:ring-accent" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod' . icon('social/castopod', 'ml-1 text-lg') . '</a>',
]) ?></p>
</div>
</footer>

View File

@ -33,13 +33,13 @@
<div class="px-2 sm:px-4">
<div class="mb-2"><?= $podcast->description_html ?></div>
<div class="flex gap-x-4 gap-y-2">
<span class="px-2 py-1 text-sm font-semibold text-gray-800 bg-gray-100 border">
<span class="px-2 py-1 text-sm font-semibold border rounded-sm border-subtle bg-highlight text-skin-muted">
<?= lang(
'Podcast.category_options.' . $podcast->category->code,
) ?>
</span>
<?php foreach ($podcast->other_categories as $other_category): ?>
<span class="px-2 py-1 text-sm font-semibold text-gray-800 bg-gray-100 border">
<span class="px-2 py-1 text-sm font-semibold border rounded-sm border-subtle bg-highlight text-skin-muted">
<?= lang(
'Podcast.category_options.' . $other_category->code,
) ?>
@ -49,11 +49,11 @@
<div class="flex items-center mt-4 gap-x-8">
<?php if ($podcast->persons !== []): ?>
<button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-castopod" data-toggle="persons-list" data-toggle-class="hidden">
<button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
<div class="inline-flex flex-row-reverse">
<?php $i = 0; ?>
<?php foreach ($podcast->persons as $person): ?>
<img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 h-8 -ml-5 border-2 rounded-full border-pine-100 last:ml-0" />
<img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 h-8 -ml-5 border-2 rounded-full border-background-base last:ml-0" />
<?php $i++; if ($i === 3) {
break;
}?>

View File

@ -29,7 +29,7 @@
<?= $this->section('content') ?>
<?php if (can_user_interact()): ?>
<form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 bg-white shadow gap-x-2 rounded-conditional-2xl">
<form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
<?= csrf_field() ?>
<?= view('_message_block') ?>
@ -50,7 +50,7 @@
<Button variant="primary" size="small" type="submit" class="self-end" iconRight="send-plane"><?= lang('Post.form.submit') ?></Button>
</div>
</form>
<hr class="my-4 border-2 border-pine-100">
<hr class="my-4 border-subtle">
<?php endif; ?>
<div class="flex flex-col gap-y-4">

View File

@ -44,20 +44,20 @@
<?php endif; ?>
</h1>
<?php if ($activeQuery): ?>
<button id="episode-lists-dropdown" type="button" class="inline-flex items-center px-2 py-1 text-sm font-semibold focus:ring-castopod" data-dropdown="button" data-dropdown-target="episode-lists-dropdown-menu" aria-label="<?= lang('Common.more') ?>" aria-haspopup="true" aria-expanded="false">
<button id="episode-lists-dropdown" type="button" class="inline-flex items-center px-2 py-1 text-sm font-semibold focus:ring-accent" data-dropdown="button" data-dropdown-target="episode-lists-dropdown-menu" aria-label="<?= lang('Common.more') ?>" aria-haspopup="true" aria-expanded="false">
<?= $activeQuery['label'] . icon('caret-down', 'ml-2 text-xl') ?>
</button>
<nav id="episode-lists-dropdown-menu" class="flex flex-col py-2 text-black bg-white border rounded shadow" aria-labelledby="episode-lists-dropdown" data-dropdown="menu" data-dropdown-placement="bottom-end">
<nav id="episode-lists-dropdown-menu" class="flex flex-col py-2 rounded-lg shadow border-3 border-contrast bg-elevated" aria-labelledby="episode-lists-dropdown" data-dropdown="menu" data-dropdown-placement="bottom-end">
<?php foreach ($episodesNav as $link): ?>
<?= anchor(
$link['route'],
$link['label'] . ' (' . $link['number_of_episodes'] . ')',
[
'class' =>
'px-2 py-1 whitespace-nowrap ' .
'px-2 py-1 whitespace-nowrap hover:bg-highlight ' .
($link['is_active']
? 'font-semibold'
: 'text-gray-600 hover:text-gray-900'),
: 'text-skin-muted hover:text-skin-base'),
],
) ?>
<?php endforeach; ?>

Some files were not shown because too many files have changed in this diff Show More