Merge branch 'develop' into mkjs-n

This commit is contained in:
tamaina 2023-05-27 15:44:57 +00:00
commit 53ad4b18e5
17 changed files with 229 additions and 597 deletions

View file

@ -14,8 +14,8 @@
>
<MkEmojiPicker
ref="picker"
class="ryghynhb _popup _shadow"
:class="{ drawer: type === 'drawer' }"
class="_popup _shadow"
:class="{ [$style.drawer]: type === 'drawer' }"
:showPinned="showPinned"
:asReactionPicker="asReactionPicker"
:asDrawer="type === 'drawer'"
@ -67,12 +67,10 @@ function opening() {
}
</script>
<style lang="scss" scoped>
.ryghynhb {
&.drawer {
<style lang="scss" module>
.drawer {
border-radius: 24px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}
</style>

View file

@ -1,78 +0,0 @@
<template>
<MkModal ref="modal" :zPriority="'middle'" @click="modal.close()" @closed="emit('closed')">
<div class="xubzgfga">
<header>{{ image.name }}</header>
<img :src="image.url" :alt="image.comment" :title="image.comment" @click="modal.close()"/>
<footer>
<span>{{ image.type }}</span>
<span>{{ bytes(image.size) }}</span>
<span v-if="image.properties && image.properties.width">{{ number(image.properties.width) }}px × {{ number(image.properties.height) }}px</span>
</footer>
</div>
</MkModal>
</template>
<script lang="ts" setup>
import { } from 'vue';
import * as misskey from 'misskey-js';
import bytes from '@/filters/bytes';
import number from '@/filters/number';
import MkModal from '@/components/MkModal.vue';
const props = withDefaults(defineProps<{
image: misskey.entities.DriveFile;
}>(), {
});
const emit = defineEmits<{
(ev: 'closed'): void;
}>();
const modal = $shallowRef<InstanceType<typeof MkModal>>();
</script>
<style lang="scss" scoped>
.xubzgfga {
margin: auto;
display: flex;
flex-direction: column;
height: 100%;
> header,
> footer {
align-self: center;
display: inline-block;
padding: 6px 9px;
font-size: 90%;
background: rgba(0, 0, 0, 0.5);
border-radius: 6px;
color: #fff;
}
> header {
margin-bottom: 8px;
opacity: 0.9;
}
> img {
display: block;
flex: 1;
min-height: 0;
object-fit: contain;
width: 100%;
cursor: zoom-out;
image-orientation: from-image;
}
> footer {
margin-top: 8px;
opacity: 0.8;
> span + span {
margin-left: 0.5em;
padding-left: 0.5em;
border-left: solid 1px rgba(255, 255, 255, 0.5);
}
}
}
</style>

View file

@ -1,182 +0,0 @@
<template>
<MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')">
<div ref="rootEl" class="hrmcaedk" :style="{ width: `${width}px`, height: (height ? `min(${height}px, 100%)` : '100%') }">
<div class="header" @contextmenu="onContextmenu">
<button v-if="history.length > 0" v-tooltip="i18n.ts.goBack" class="_button" @click="back()"><i class="ti ti-arrow-left"></i></button>
<span v-else style="display: inline-block; width: 20px"></span>
<span v-if="pageMetadata?.value" class="title">
<i v-if="pageMetadata?.value.icon" class="icon" :class="pageMetadata?.value.icon"></i>
<span>{{ pageMetadata?.value.title }}</span>
</span>
<button class="_button" @click="$refs.modal.close()"><i class="ti ti-x"></i></button>
</div>
<div class="body" style="container-type: inline-size;">
<MkStickyContainer>
<template #header><MkPageHeader v-if="pageMetadata?.value && !pageMetadata?.value.hideHeader" :info="pageMetadata?.value"/></template>
<RouterView :router="router"/>
</MkStickyContainer>
</div>
</div>
</MkModal>
</template>
<script lang="ts" setup>
import { ComputedRef, provide } from 'vue';
import MkModal from '@/components/MkModal.vue';
import { popout as _popout } from '@/scripts/popout';
import copyToClipboard from '@/scripts/copy-to-clipboard';
import { url } from '@/config';
import * as os from '@/os';
import { mainRouter, routes } from '@/router';
import { i18n } from '@/i18n';
import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata';
import { Router } from '@/nirax';
const props = defineProps<{
initialPath: string;
}>();
defineEmits<{
(ev: 'closed'): void;
(ev: 'click'): void;
}>();
const router = new Router(routes, props.initialPath);
router.addListener('push', ctx => {
});
let pageMetadata = $ref<null | ComputedRef<PageMetadata>>();
let rootEl = $ref();
let modal = $shallowRef<InstanceType<typeof MkModal>>();
let path = $ref(props.initialPath);
let width = $ref(860);
let height = $ref(660);
const history = [];
provide('router', router);
provideMetadataReceiver((info) => {
pageMetadata = info;
});
provide('shouldOmitHeaderTitle', true);
provide('shouldHeaderThin', true);
const pageUrl = $computed(() => url + path);
const contextmenu = $computed(() => {
return [{
type: 'label',
text: path,
}, {
icon: 'ti ti-player-eject',
text: i18n.ts.showInPage,
action: expand,
}, {
icon: 'ti ti-window-maximize',
text: i18n.ts.popout,
action: popout,
}, null, {
icon: 'ti ti-external-link',
text: i18n.ts.openInNewTab,
action: () => {
window.open(pageUrl, '_blank');
modal.close();
},
}, {
icon: 'ti ti-link',
text: i18n.ts.copyLink,
action: () => {
copyToClipboard(pageUrl);
},
}];
});
function navigate(path, record = true) {
if (record) history.push(router.getCurrentPath());
router.push(path);
}
function back() {
navigate(history.pop(), false);
}
function expand() {
mainRouter.push(path);
modal.close();
}
function popout() {
_popout(path, rootEl);
modal.close();
}
function onContextmenu(ev: MouseEvent) {
os.contextMenu(contextmenu, ev);
}
</script>
<style lang="scss" scoped>
.hrmcaedk {
margin: auto;
overflow: hidden;
display: flex;
flex-direction: column;
contain: content;
border-radius: var(--radius);
--root-margin: 24px;
@media (max-width: 500px) {
--root-margin: 16px;
}
> .header {
$height: 52px;
$height-narrow: 42px;
display: flex;
flex-shrink: 0;
height: $height;
line-height: $height;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background: var(--windowHeader);
-webkit-backdrop-filter: var(--blur, blur(15px));
backdrop-filter: var(--blur, blur(15px));
> button {
height: $height;
width: $height;
&:hover {
color: var(--fgHighlighted);
}
}
@media (max-width: 500px) {
height: $height-narrow;
line-height: $height-narrow;
padding-left: 16px;
> button {
height: $height-narrow;
width: $height-narrow;
}
}
> .title {
flex: 1;
> .icon {
margin-right: 0.5em;
}
}
}
> .body {
overflow: auto;
background: var(--bg);
}
}
</style>

View file

@ -1,12 +1,12 @@
<template>
<div class="adhpbeos">
<div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ disabled, focused, tall, pre }">
<div>
<div :class="$style.label" @click="focus"><slot name="label"></slot></div>
<div :class="{ [$style.disabled]: disabled, [$style.focused]: focused, [$style.tall]: tall, [$style.pre]: pre }" style="position: relative;">
<textarea
ref="inputEl"
v-model="v"
v-adaptive-border
:class="{ code, _monospace: code }"
:class="[$style.textarea, { [$style.code]: code, _monospace: code }]"
:disabled="disabled"
:required="required"
:readonly="readonly"
@ -20,9 +20,9 @@
@input="onInput"
></textarea>
</div>
<div class="caption"><slot name="caption"></slot></div>
<div :class="$style.caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
</div>
</template>
@ -111,9 +111,8 @@ onMounted(() => {
});
</script>
<style lang="scss" scoped>
.adhpbeos {
> .label {
<style lang="scss" module>
.label {
font-size: 0.85em;
padding: 0 0 8px 0;
user-select: none;
@ -123,7 +122,7 @@ onMounted(() => {
}
}
> .caption {
.caption {
font-size: 0.85em;
padding: 8px 0 0 0;
color: var(--fgTransparentWeak);
@ -133,10 +132,7 @@ onMounted(() => {
}
}
> .input {
position: relative;
> textarea {
.textarea {
appearance: none;
-webkit-appearance: none;
display: block;
@ -163,35 +159,34 @@ onMounted(() => {
}
}
&.focused {
> textarea {
.focused {
> .textarea {
border-color: var(--accent) !important;
}
}
&.disabled {
.disabled {
opacity: 0.7;
cursor: not-allowed !important;
&, * {
> .textarea {
cursor: not-allowed !important;
}
}
&.tall {
> textarea {
.tall {
> .textarea {
min-height: 200px;
}
}
&.pre {
> textarea {
.pre {
> .textarea {
white-space: pre;
}
}
}
> .save {
.save {
margin: 8px 0 0 0;
}
}
</style>

View file

@ -1,19 +1,19 @@
<template>
<div class="ffcbddfc" :class="{ inline }">
<a v-if="external" class="main _button" :href="to" target="_blank">
<span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span>
<span class="right">
<span class="text"><slot name="suffix"></slot></span>
<i class="ti ti-external-link icon"></i>
<div :class="[$style.root, { [$style.inline]: inline }]">
<a v-if="external" :class="$style.main" class="_button" :href="to" target="_blank">
<span :class="$style.icon"><slot name="icon"></slot></span>
<span :class="$style.text"><slot></slot></span>
<span :class="$style.suffix">
<span :class="$style.suffixText"><slot name="suffix"></slot></span>
<i class="ti ti-external-link" :class="$style.suffixIcon"></i>
</span>
</a>
<MkA v-else class="main _button" :class="{ active }" :to="to" :behavior="behavior">
<span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span>
<span class="right">
<span class="text"><slot name="suffix"></slot></span>
<i class="ti ti-chevron-right icon"></i>
<MkA v-else :class="[$style.main, { [$style.active]: active }]" class="_button" :to="to" :behavior="behavior">
<span :class="$style.icon"><slot name="icon"></slot></span>
<span :class="$style.text"><slot></slot></span>
<span :class="$style.suffix">
<span :class="$style.suffixText"><slot name="suffix"></slot></span>
<i class="ti ti-chevron-right" :class="$style.suffixIcon"></i>
</span>
</MkA>
</div>
@ -26,20 +26,21 @@ const props = defineProps<{
to: string;
active?: boolean;
external?: boolean;
behavior?: null | 'window' | 'browser' | 'modalWindow';
behavior?: null | 'window' | 'browser';
inline?: boolean;
}>();
</script>
<style lang="scss" scoped>
.ffcbddfc {
<style lang="scss" module>
.root {
display: block;
&.inline {
display: inline-block;
}
}
> .main {
.main {
display: flex;
align-items: center;
width: 100%;
@ -58,8 +59,9 @@ const props = defineProps<{
color: var(--accent);
background: var(--buttonHoverBg);
}
}
> .icon {
.icon {
margin-right: 0.75em;
flex-shrink: 0;
text-align: center;
@ -74,22 +76,20 @@ const props = defineProps<{
}
}
> .text {
.text {
flex-shrink: 1;
white-space: normal;
padding-right: 12px;
text-align: center;
}
> .right {
.suffix {
margin-left: auto;
opacity: 0.7;
white-space: nowrap;
> .text:not(:empty) {
> .suffixText:not(:empty) {
margin-right: 0.75em;
}
}
}
}
</style>

View file

@ -1,5 +1,4 @@
<template>
<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
<div v-if="pending">
<MkLoading/>
</div>
@ -7,12 +6,11 @@
<slot :result="result"></slot>
</div>
<div v-else>
<div class="wszdbhzo">
<div :class="$style.error">
<div><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</div>
<MkButton inline class="retry" @click="retry"><i class="ti ti-reload"></i> {{ i18n.ts.retry }}</MkButton>
<MkButton inline style="margin-top: 16px;" @click="retry"><i class="ti ti-reload"></i> {{ i18n.ts.retry }}</MkButton>
</div>
</div>
</Transition>
</template>
<script lang="ts" setup>
@ -60,22 +58,9 @@ const retry = () => {
};
</script>
<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.125s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.wszdbhzo {
<style lang="scss" module>
.error {
padding: 16px;
text-align: center;
> .retry {
margin-top: 16px;
}
}
</style>

View file

@ -15,7 +15,7 @@ import { useRouter } from '@/router';
const props = withDefaults(defineProps<{
to: string;
activeClass?: null | string;
behavior?: null | 'window' | 'browser' | 'modalWindow';
behavior?: null | 'window' | 'browser';
}>(), {
activeClass: null,
behavior: null,
@ -70,14 +70,6 @@ function openWindow() {
os.pageWindow(props.to);
}
function modalWindow() {
os.modalPageWindow(props.to);
}
function popout() {
popout_(props.to);
}
function nav(ev: MouseEvent) {
if (props.behavior === 'browser') {
location.href = props.to;
@ -87,8 +79,6 @@ function nav(ev: MouseEvent) {
if (props.behavior) {
if (props.behavior === 'window') {
return openWindow();
} else if (props.behavior === 'modalWindow') {
return modalWindow();
}
}

View file

@ -1,8 +1,8 @@
<template>
<section class="sdgxphyu">
<component :is="'h' + h">{{ block.title }}</component>
<section>
<component :is="'h' + h" :class="h < 5 ? $style['h' + h] : null">{{ block.title }}</component>
<div class="children">
<div class="_gaps">
<XBlock v-for="child in block.children" :key="child.id" :page="page" :block="child" :h="h + 1"/>
</div>
</section>
@ -22,27 +22,19 @@ defineProps<{
}>();
</script>
<style lang="scss" scoped>
.sdgxphyu {
margin: 1.5em 0;
> h2 {
<style lang="scss" module>
.h2 {
font-size: 1.35em;
margin: 0 0 0.5em 0;
}
> h3 {
.h3 {
font-size: 1em;
margin: 0 0 0.5em 0;
}
> h4 {
.h4 {
font-size: 1em;
margin: 0 0 0.5em 0;
}
> .children {
//padding 16px
}
}
</style>

View file

@ -1,7 +1,7 @@
<template>
<div class="mrdgzndn">
<div class="_gaps">
<Mfm :text="block.text" :isNote="false" :i="$i"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" class="url"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url"/>
</div>
</template>
@ -22,19 +22,3 @@ const props = defineProps<{
const urls = props.block.text ? extractUrlFromMfm(mfm.parse(props.block.text)) : [];
</script>
<style lang="scss" scoped>
.mrdgzndn {
&:not(:first-child) {
margin-top: 0.5em;
}
&:not(:last-child) {
margin-bottom: 0.5em;
}
> .url {
margin: 0.5em 0;
}
}
</style>

View file

@ -1,5 +1,5 @@
<template>
<div class="iroscrza" :class="{ center: page.alignCenter, serif: page.font === 'serif' }">
<div :class="{ [$style.center]: page.alignCenter, [$style.serif]: page.font === 'serif' }">
<XBlock v-for="child in page.content" :key="child.id" :block="child" :h="2"/>
</div>
</template>
@ -14,16 +14,12 @@ defineProps<{
}>();
</script>
<style lang="scss" scoped>
.iroscrza {
&.serif {
> div {
<style lang="scss" module>
.serif {
font-family: serif;
}
}
&.center {
.center {
text-align: center;
}
}
</style>

View file

@ -172,12 +172,6 @@ export function pageWindow(path: string) {
}, {}, 'closed');
}
export function modalPageWindow(path: string) {
popup(defineAsyncComponent(() => import('@/components/MkModalPageWindow.vue')), {
initialPath: path,
}, {}, 'closed');
}
export function toast(message: string) {
popup(MkToast, {
message,

View file

@ -5,10 +5,10 @@
<div class="_gaps">
<div v-for="relay in relays" :key="relay.inbox" class="relaycxt _panel" style="padding: 16px;">
<div>{{ relay.inbox }}</div>
<div class="status">
<i v-if="relay.status === 'accepted'" class="ti ti-check icon accepted"></i>
<i v-else-if="relay.status === 'rejected'" class="ti ti-ban icon rejected"></i>
<i v-else class="ti ti-clock icon requesting"></i>
<div style="margin: 8px 0;">
<i v-if="relay.status === 'accepted'" class="ti ti-check" :class="$style.icon" style="color: var(--success);"></i>
<i v-else-if="relay.status === 'rejected'" class="ti ti-ban" :class="$style.icon" style="color: var(--error);"></i>
<i v-else class="ti ti-clock" :class="$style.icon"></i>
<span>{{ i18n.t(`_relayStatus.${relay.status}`) }}</span>
</div>
<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
@ -83,23 +83,9 @@ definePageMetadata({
});
</script>
<style lang="scss" scoped>
.relaycxt {
> .status {
margin: 8px 0;
> .icon {
<style lang="scss" module>
.icon {
width: 1em;
margin-right: 0.75em;
&.accepted {
color: var(--success);
}
&.rejected {
color: var(--error);
}
}
}
}
</style>

View file

@ -2,29 +2,29 @@
<MkStickyContainer>
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :contentMax="700">
<div v-if="tab === 'featured'" class="">
<div v-if="tab === 'featured'">
<MkPagination v-slot="{items}" :pagination="featuredFlashsPagination">
<div class="_gaps_s">
<MkFlashPreview v-for="flash in items" :key="flash.id" class="" :flash="flash"/>
<MkFlashPreview v-for="flash in items" :key="flash.id" :flash="flash"/>
</div>
</MkPagination>
</div>
<div v-else-if="tab === 'my'" class="my">
<div v-else-if="tab === 'my'">
<div class="_gaps">
<MkButton class="new" gradate rounded style="margin: 0 auto;" @click="create()"><i class="ti ti-plus"></i></MkButton>
<MkButton gradate rounded style="margin: 0 auto;" @click="create()"><i class="ti ti-plus"></i></MkButton>
<MkPagination v-slot="{items}" :pagination="myFlashsPagination">
<div class="_gaps_s">
<MkFlashPreview v-for="flash in items" :key="flash.id" class="" :flash="flash"/>
<MkFlashPreview v-for="flash in items" :key="flash.id" :flash="flash"/>
</div>
</MkPagination>
</div>
</div>
<div v-else-if="tab === 'liked'" class="">
<div v-else-if="tab === 'liked'">
<MkPagination v-slot="{items}" :pagination="likedFlashsPagination">
<div class="_gaps_s">
<MkFlashPreview v-for="like in items" :key="like.flash.id" class="" :flash="like.flash"/>
<MkFlashPreview v-for="like in items" :key="like.flash.id" :flash="like.flash"/>
</div>
</MkPagination>
</div>
@ -87,21 +87,3 @@ definePageMetadata(computed(() => ({
icon: 'ti ti-player-play',
})));
</script>
<style lang="scss" scoped>
.rknalgpo {
&.my .ckltabjg:first-child {
margin-top: 16px;
}
.ckltabjg:not(:last-child) {
margin-bottom: 8px;
}
@media (min-width: 500px) {
.ckltabjg:not(:last-child) {
margin-bottom: 16px;
}
}
}
</style>

View file

@ -2,14 +2,16 @@
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :contentMax="700">
<div class="qkcjvfiv">
<MkButton primary class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.createList }}</MkButton>
<div class="_gaps">
<MkButton primary rounded style="margin: 0 auto;" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.createList }}</MkButton>
<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination" class="lists">
<MkA v-for="list in items" :key="list.id" class="list _panel" :to="`/my/lists/${ list.id }`">
<div class="name">{{ list.name }}</div>
<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination">
<div class="_gaps">
<MkA v-for="list in items" :key="list.id" class="_panel" :class="$style.list" :to="`/my/lists/${ list.id }`">
<div style="margin-bottom: 4px;">{{ list.name }}</div>
<MkAvatars :userIds="list.userIds"/>
</MkA>
</div>
</MkPagination>
</div>
</MkSpacer>
@ -58,14 +60,8 @@ definePageMetadata({
});
</script>
<style lang="scss" scoped>
.qkcjvfiv {
> .add {
margin: 0 auto var(--margin) auto;
}
> .lists {
> .list {
<style lang="scss" module>
.list {
display: block;
padding: 16px;
border: solid 1px var(--divider);
@ -76,11 +72,5 @@ definePageMetadata({
border: solid 1px var(--accent);
text-decoration: none;
}
> .name {
margin-bottom: 4px;
}
}
}
}
</style>

View file

@ -16,7 +16,7 @@
</component>
</template>
<div class="divider"></div>
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="i18n.ts.controlPanel" class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="i18n.ts.controlPanel" class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'window' : null">
<i class="ti ti-dashboard ti-fw"></i>
</MkA>
<button v-click-anime class="item _button" @click="more">
@ -25,7 +25,7 @@
</button>
</div>
<div class="right">
<MkA v-click-anime v-tooltip="i18n.ts.settings" class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
<MkA v-click-anime v-tooltip="i18n.ts.settings" class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'window' : null">
<i class="ti ti-settings ti-fw"></i>
</MkA>
<button v-click-anime class="item _button account" @click="openAccountMenu">

View file

@ -20,14 +20,14 @@
</component>
</template>
<div class="divider"></div>
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'window' : null">
<i class="ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
</MkA>
<button v-click-anime class="item _button" @click="more">
<i class="ti ti-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
</button>
<MkA v-click-anime class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
<MkA v-click-anime class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'window' : null">
<i class="ti ti-settings ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
</MkA>
<div class="divider"></div>

View file

@ -328,12 +328,12 @@ async function deleteProfile() {
flex-direction: column;
scroll-snap-align: start;
flex-shrink: 0;
margin-top: var(--columnGap);
margin-bottom: var(--columnGap);
margin-right: var(--columnGap);
padding-top: var(--columnGap);
padding-bottom: var(--columnGap);
padding-right: var(--columnGap);
&:first-of-type {
margin-left: var(--columnGap);
padding-left: var(--columnGap);
}
> .column:not(:last-of-type) {