24 コミット

作成者 SHA1 メッセージ 日付
みてるぞ 16c99894c7 名前空間の参照ちょっと修正 2024-02-14 12:48:11 +09:00
みてるぞ d467d82a3e DAO について修正 2024-02-13 12:49:38 +09:00
みてるぞ 2ade56a952 Dao\Thread :: find 追加 2024-02-13 08:34:31 +09:00
みてるぞ dd3a9027d5 DAO 修正 2024-02-12 13:00:15 +09:00
mitenaizo 1ae5df5420 ファイル構成変更 2024-02-12 03:24:36 +09:00
みてるぞ 445d6da9ef ちDAOょっと呼出 2024-02-09 12:49:20 +09:00
みてるぞ 5a0cefbfbb リファクタリング 2024-02-09 03:55:02 +09:00
みてるぞ 837b3aaab5 DAO にメソッド追加 2024-02-08 01:02:59 +09:00
みてるぞ 34859e55b3 スレッドの削除 DAO 追加 2024-02-07 12:50:57 +09:00
みてるぞ efa4ceedf8 DAO 追加 2024-02-07 04:13:28 +09:00
みてるぞ 4b89165f8e DTO 追加 2024-02-07 03:42:00 +09:00
みてるぞ dca71147b4 移行用 SQL 追加 2024-02-03 03:34:27 +09:00
miteruzo 493bc71c94 フォントのリンク解除(OSDN 鯖落ち) 2024-02-03 01:21:14 +09:00
Gitea d22a00ced7 なぜこれで動いてた…… 2023-10-29 16:02:25 +09:00
みてるぞ 403c67178b 空白の削除 2023-10-29 15:10:12 +09:00
みてるぞ f0e267507e Merge pull request 'KEKEC_BBS_DEV-001' (#5) from KEKEC_BBS_DEV-001 into main
Reviewed-on: #5
2023-10-29 14:56:14 +09:00
みてるぞ 60b82f2ae2 Merge branch 'main' into KEKEC_BBS_DEV-001 2023-10-29 14:53:06 +09:00
みてるぞ 6c4e401d5a コーディング・スタイルの調整 2023-10-29 14:49:18 +09:00
みてるぞ 26d78aab88 修正 2023-09-01 02:06:03 +09:00
みてるぞ d13588c24f 本日作業分 2023-09-01 01:53:54 +09:00
みてるぞ 50996316e5 本日作業分 2023-09-01 01:03:57 +09:00
Gitea 34758dfa19 database.php の追加 2023-08-07 01:26:21 +09:00
Gitea a7a601c769 レイア削除で reDraw するやぅに変更 2023-07-09 19:30:31 +09:00
Gitea 0a96136e34 URL を相対パスにした. 2023-06-17 00:02:22 +09:00
22個のファイルの変更590行の追加2688行の削除
+5 -3
ファイルの表示
@@ -1,3 +1,5 @@
/image /images
/draft /drafts
/database.php
/db.sqlite3
/www/images
+99
ファイルの表示
@@ -0,0 +1,99 @@
<?php
namespace Dao;
class
Response
{
public static function
fetch_all (
\SQLite3 $db,
int $thread_id)
: array
{
$sql = "
SELECT
thread_id,
response_id,
name,
message,
date,
image,
held,
deleted,
pass,
good,
bad
FROM
responses
WHERE
id = $thread_id";
$result = $db -> query ($sql);
$responses = [];
while (($row = $result -> fetchArray (SQLITE_ASSOC)) !== false)
{
$response = new Dto\Response;
$response -> thread_id = $row['thread_id'];
$response -> response_id = $row['response_id'];
$response -> name = $row['name'];
$response -> message = $row['message'];
$response -> date = $row['date'];
$response -> image = $row['image'];
$response -> held = $row['held'];
$response -> deleted = $row['deleted'];
$response -> pass = $row['pass'];
$response -> good = $row['good'];
$response -> bad = $row['bad'];
$responses[] = $response;
}
return $responses;
}
public static function
like (
\SQLite3 $db,
int $thread_id,
int $response_id)
: void
{
$sql = "
UPDATE
responses
SET
good = good + 1
WHERE
(thread_id = $thread_id)
AND (response_id = $response_id)";
$db -> query ($sql);
}
public static function
dislike (
\SQLite3 $db,
int $thread_id,
int $response_id)
: void
{
$sql = "
UPDATE
responses
SET
bad = bad + 1
WHERE
(thread_id = $thread_id)
AND (response_id = $response_id)";
$db -> query ($sql);
}
}
+124
ファイルの表示
@@ -0,0 +1,124 @@
<?php
namespace Dao;
class
Thread
{
public static function
fetch_all (
\SQLite3 $db)
: array
{
$sql = "
SELECT
t.id,
t.title,
t.explain,
MAX(r.date) AS latest
FROM
threads AS t
LEFT OUTER JOIN
responses AS r
ON
r.thread_id = t.id
WHERE
t.id <> 1
-- AND t.deleted = 0
GROUP BY
t.id
ORDER BY
latest DESC";
$result = $db -> query ($sql);
$threads = [];
while (($row = $result -> fetchArray (SQLITE3_ASSOC)) !== false)
{
$thread = new Dto\Thread;
$thread -> id = $row['id'];
$therad -> title = $row['title'];
$thread -> explain = $row['explain'];
$thread -> latest = $row['latest'];
$threads[] = $thread;
}
return $therads;
}
public static function
find (
\SQLite3 $db,
int $id)
: ?\Dto\Thread
{
$sql = "
SELECT
t.id,
t.title,
t.explain,
MAX(r.date) AS latest
FROM
threads AS t
LEFT OUTER JOIN
responses AS r
ON
r.thread_id = t.id
WHERE
t.id = $id
GROUP BY
t.id
ORDER BY
latest DESC";
$result = $db -> query ($sql);
if ($row === false)
return null;
$row = $result -> fetchArray (SQLITE3_ASSOC);
if ($row === false)
return null;
$thread = new \Dto\Thread;
$thread -> id = $row['id'];
$thread -> title = $row['title'];
$thread -> explain = $row['explain'];
$thread -> length = $row['length'];
return $thread;
}
public static function
create_thread (
\SQLite3 $db,
string $title,
string $explain)
: void
{
;
}
public static function
delete_thread (
\SQLite3 $db,
int $id)
: void
{
$db -> query ("
DELETE FROM
threads
WHERE
id = $id");
}
}
+21
ファイルの表示
@@ -0,0 +1,21 @@
<?php
namespace Dto;
class
Response
{
public int $thread_id;
public int $response_id;
public string $name;
public ?string $message;
public DateTime $date;
public string $image;
public bool $held;
public bool $deleted;
public ?string $pass;
public int $good;
public int $bad;
}
+15
ファイルの表示
@@ -0,0 +1,15 @@
<?php
namespace Dto;
class
Thread
{
public int $id;
public string $title;
public ?string $explain;
public ?DateTime $latest;
public bool $deleted;
}
+4 -5
ファイルの表示
@@ -4,8 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="robots" content="noindex" /> <meta name="robots" content="noindex" />
<title><?= ($title == '') ? '' : ($title . ' - ') ?>キケッツチャンネル お絵描き掲示板</title> <title><?= ($title == '') ? '' : ($title . ' - ') ?>キケッツチャンネル お絵描き掲示板</title>
<link rel="stylesheet" href="https://jpafonts.osdn.jp/webfonts/jpafonts.css" /> <!-- <link rel="stylesheet" href="https://jpafonts.osdn.jp/webfonts/jpafonts.css" /> -->
<link rel="stylesheet" type="text/css" href="/style.css" />
<link rel="stylesheet" type="text/css" href="./styles/style.css" /> <link rel="stylesheet" type="text/css" href="./styles/style.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" /> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" />
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script> <script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script>
@@ -42,11 +41,11 @@
</div> </div>
</div> </div>
<h1><a href="."><img src="/img/kusobbs.gif" alt="クソ掲示板" style="width: 398px" /></a></h1> <h1><a href="."><img src="/assets/kusobbs.gif" alt="クソ掲示板" style="width: 398px" /></a></h1>
<div style="text-align: center"><a href="#" onclick="PauseMusic ()" id="mute">&emsp;</a></div> <div style="text-align: center"><a href="#" onclick="PauseMusic ()" id="mute">&emsp;</a></div>
<?php if ($thread == -1): ?> <?php if ($thread == -1): ?>
<form action="make_thread.php" method="POST"> <form action="./modules/make_thread.php" method="POST">
スレ名:<input type="text" name="thread-name" /><br /> スレ名:<input type="text" name="thread-name" /><br />
スレ内容:<textarea name="thread-explain"></textarea><br /> スレ内容:<textarea name="thread-explain"></textarea><br />
<input type="submit" value="スレ立て" /> <input type="submit" value="スレ立て" />
@@ -302,7 +301,7 @@
<canvas style="display: none" width="1" height="1" id="work"></canvas> <canvas style="display: none" width="1" height="1" id="work"></canvas>
<canvas style="display: none" width="480" height="480" id="canvas-perfect"></canvas> <canvas style="display: none" width="480" height="480" id="canvas-perfect"></canvas>
<script type="text/javascript" src="script.js"></script> <script type="text/javascript" src="./scripts/script.js"></script>
<?php if ($thread != -1): ?> <?php if ($thread != -1): ?>
<script type="text/javascript" src="./scripts/paint.js"></script> <script type="text/javascript" src="./scripts/paint.js"></script>
+7
ファイルの表示
@@ -0,0 +1,7 @@
<?php
require_once __DIR__ . '/daos/response.php';
require_once __DIR__ . '/daos/thread.php';
require_once __DIR__ . '/dtos/response.php';
require_once __DIR__ . '/dtos/thread.php';
-60
ファイルの表示
@@ -1,60 +0,0 @@
<?php
require_once "${_SERVER['DOCUMENT_ROOT']}/database.php";
if (isset ($_GET['page'])):
$page = $_GET['page'];
else:
$page = 0;
endif;
if (isset ($_GET['thread'])):
$thread = $_GET['thread'];
else:
$thread = -1;
endif;
if (isset ($_GET['sort'])):
$sort = $_GET['sort'];
if (!(in_array ($sort, array ('td', 'eg', 'ta', 'eb')))):
$sort = 'td';
endif;
else:
$sort = 'td';
endif;
// 画像のディレクトリを開く.
$dir = 'image/';
$handle = opendir ($dir);
// MySQL 宣言
$mysqli = set_mysql ('miteruzo_bbs');
$mysqli -> set_charset ('utf8');
if ($result = $mysqli -> query ("SELECT * FROM threads WHERE id = $thread")):
$row = $result -> fetch_assoc ();
$title = $row['title'];
$explain = $row['explain'];
$result -> close ();
endif;
if (isset ($_GET['id'])
&& isset ($_GET['evaluate'])
&& (($_GET['evaluate'] == 'good') || ($_GET['evaluate'] == 'bad'))):
$mysqli -> query ("
UPDATE
responses
SET
{$_GET['evaluate']} = {$_GET['evaluate']} + 1
WHERE
(thread_id = $thread) AND (response_id = {$_GET['id']})");
header ("Location: ./?thread=$thread&sort=$sort");
endif;
require_once './forms/index.frm.php';
+1
ファイルの表示
@@ -0,0 +1 @@
CREATE TABLE `threads` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT , `title` TEXT NOT NULL, `explain` TEXT NOT NULL , `latest` TEXT NOT NULL , `length` INTEGER NOT NULL DEFAULT 0) ;
+2
ファイルの表示
@@ -0,0 +1,2 @@
CREATE TABLE `responses` ( `thread_id` INTEGER , `response_id` INTEGER , `name` TEXT NOT NULL DEFAULT '名なしさん' , `message` TEXT NOT NULL , `date` TEXT NOT NULL , `image` TEXT NOT NULL , `held` INTEGER NOT NULL DEFAULT 0 , `deleted` INTEGER NOT NULL DEFAULT 0 , `pass` TEXT NULL , `good` INTEGER NOT NULL DEFAULT 0, `bad` INTEGER NOT NULL DEFAULT 0 , PRIMARY KEY(thread_id, response_id ));
+9 -3
ファイルの表示
@@ -1,17 +1,19 @@
<?php <?php
define ('SAVE_DIR', 'draft/'); define ('SAVE_DIR', "${_SERVER['DOCUMENT_ROOT']}/drafts/");
$json = getParamJSON (); $json = getParamJSON ();
if (!(isset ($json['data']))) if (!(isset ($json['data'])))
{ {
sendResult (false, 'Empty query Parameter: data'); sendResult (false, 'Empty query Parameter: data');
exit (1); exit (1);
} }
if (!(preg_match ('/^data:image\/png;base64,/', $json['data']))) if (!(preg_match ('/^data:image\/png;base64,/', $json['data'])))
{ {
sendResult (false, 'Not Allow data type: data'); sendResult (false, 'Not Allow data type: data');
exit (1); exit (1);
} }
@@ -27,7 +29,8 @@ setcookie ('backup', $file, time () + 60 * 60 * 24 * 30);
function function
getParamJSON () getParamJSON ():
array
{ {
$buff = file_get_contents ('php://input'); $buff = file_get_contents ('php://input');
$json = json_decode ($buff, true); $json = json_decode ($buff, true);
@@ -36,7 +39,10 @@ getParamJSON ()
} }
function function
sendResult ($status, $data) sendResult (
$status,
$data):
string
{ {
header ('Access-Control-Allow-Origin: *'); header ('Access-Control-Allow-Origin: *');
header ('Access-Control-Allow-Headers: *'); header ('Access-Control-Allow-Headers: *');
+2 -2
ファイルの表示
@@ -28,11 +28,11 @@ if ($result = $mysqli -> query ("
WHERE WHERE
(thread_id = $thread) AND (response_id = $id)"); (thread_id = $thread) AND (response_id = $id)");
echo "消しましたぁ!!<br /><br /><img style='border: solid 1px' src='image/{$row['image']}' />"; echo "消しましたぁ!!<br /><br /><img style='border: solid 1px' src='/images/{$row['image']}' />";
else: else:
echo '残念.<br />削除用パスワードが違います.'; echo '残念.<br />削除用パスワードが違います.';
endif; endif;
echo "<br /><br />5 秒後に元のページに戻ります.<br /><br /><a href='./?thread=$thread#$id'>戻らない場合はこちら</a><script>setTimeout (function () {window.location.href = `./?thread=$thread#$id`}, 5000)</script>"; echo "<br /><br />5 秒後に元のページに戻ります.<br /><br /><a href='/?thread=$thread#$id'>戻らない場合はこちら</a><script>setTimeout (function () {window.location.href = `/?thread=$thread#$id`}, 5000)</script>";
endif; endif;
+2 -2
ファイルの表示
@@ -17,7 +17,7 @@ if (!(empty ($_POST['thread-name'])))
$result -> close (); $result -> close ();
$sql = "INSERT INTO threads (id, title, `explain`, latest, length) VALUES ($current, '{$_POST['thread-name']}', '$explain', '" . date ('Y-m-d H:i:s') . "', 0)"; $sql = "INSERT INTO threads (title, `explain`, latest, length) VALUES ('{$_POST['thread-name']}', '$explain', '" . date ('Y-m-d H:i:s') . "', 0)";
$mysqli -> query ($sql); $mysqli -> query ($sql);
/* $sql = "CREATE TABLE `miteruzo_bbs`.`thread_$current` ( /* $sql = "CREATE TABLE `miteruzo_bbs`.`thread_$current` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'レス番', `id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'レス番',
@@ -37,5 +37,5 @@ if (!(empty ($_POST['thread-name'])))
$mysqli -> close (); $mysqli -> close ();
} }
header ("location: ./?thread=$current"); header ("location: ../?thread=$current");
+2 -2
ファイルの表示
@@ -2,10 +2,10 @@
require "${_SERVER['DOCUMENT_ROOT']}/database.php"; require "${_SERVER['DOCUMENT_ROOT']}/database.php";
define ('SAVE_DIR', 'image/'); // 保存ディレクトリ定義 define ('SAVE_DIR', "${_SERVER['DOCUMENT_ROOT']}/images/"); // 保存ディレクトリ定義
$thread = $_GET['thread']; $thread = $_GET['thread'];
file_put_contents ('log.txt', $thread); // file_put_contents ('log.txt', $thread);
$json = getParamJSON (); // JSON パラメタ $json = getParamJSON (); // JSON パラメタ
-1047
ファイルの表示
ファイル差分が大きすぎるため省略します 差分を読込み
-169
ファイルの表示
@@ -1,169 +0,0 @@
const music = new Audio ('./assets/music.mp3'); // BGM
let playing = false; // 再生フラグ
let nowPlay = true; // 再生すべきかどぅか
document.getElementById ('sort').addEventListener ('change', sortChange);
/*
* BGM を再生しよぅとする.
*
* 戻り値は,なし.
*/
async function
PlayMusic ()
{
// 再生中でなぃ場合
if (playing === false)
{
// BGM を再生しよぅとする.
try
{
await music.play ();
music.loop = true;
playing = true;
nowPlay = true;
// オン/オフ・ボタン
document.getElementById ('mute').innerHTML = 'BGM がうるさい人用';
}
catch (err)
{
playing = false;
}
}
}
/*
* BGM の消音切替
*
* 戻り値は,なし.
*/
function
PauseMusic ()
{
// 切替
if (nowPlay && playing) // 再生中の場合
{
music.muted = true;
document.getElementById ('mute').innerHTML = 'やっぱり BGM が恋しい人用';
nowPlay = false;
}
else // 消音中の場合
{
music.muted = false;
document.getElementById ('mute').innerHTML = 'BGM がうるさい人用';
nowPlay = true;
}
}
// 1000 ms ごとに BGM 再生試行
window.setInterval (function
()
{
PlayMusic ();
},
1000);
// 画面クリックで BGM 再生試行
document.addEventListener ('click', function
()
{
PlayMusic ();
});
// 画面タッチで BGM 再生試行
document.addEventListener ('touchstart', function
()
{
PlayMusic ();
});
const body = document.getElementsByTagName ('body')[0]; // body 要素
const cv = document.getElementById ('work'); // 作業用 Canvas
const g = cv.getContext ('2d'); // 作業用 Canvas のコンテクスト
const list = ['magenta', 'lime', 'cyan', 'yellow', 'orange', 'pink', 'aliceblue',
'antiquewhite', 'aqua', 'aquamarine', 'bisque', 'lightgreen', 'linen',
'lightsalmon', 'darkorange', 'palegreen'];
// 色リスト
let nowColour = Math.floor (Math.random () * list.length);
// 前の色番号
let nextColour = Math.floor (Math.random () * list.length);
// 次の色番号
let [tempR, tempG, tempB] = getRGB (list[nowColour]);
// 現在の RGB 値
// 3000 ms ごとに次の色指定
window.setInterval (function
()
{
nowColour = nextColour;
nextColour = Math.floor (Math.random () * list.length);
},
3000);
// 20 ms ごとに,ぢょぢょに,色変更
window.setInterval (function
()
{
let [nowR, nowG, nowB] = getRGB (list[nowColour]);
let [nextR, nextG, nextB] = getRGB (list[nextColour]);
body.style.backgroundColor = `rgb(${tempR}, ${tempG}, ${tempB})`;
tempR += (nextR - nowR) / 150;
tempG += (nextG - nowG) / 150;
tempB += (nextB - nowB) / 150;
},
20);
/*
* カラ・コゥド c を RGB 値に変換する.
*
* 戻り値は,RGB 値排列.
*/
function
getRGB (c)
{
g.fillStyle = c;
g.fillRect (0, 0, 1, 1);
const img = g.getImageData (0, 0, 1, 1);
const px = img.data;
const rgb = [px[0], px[1], px[2]];
return rgb;
}
function
sortChange (evt)
{
const searchParams = new URLSearchParams (window.location.search);
switch (evt.currentTarget.value)
{
default:
window.location.href = `./?thread=${searchParams.get ('thread')}&sort=td`;
break;
case 'evaluate-good':
window.location.href = `./?thread=${searchParams.get ('thread')}&sort=eg`;
break;
case 'time-asc':
window.location.href = `./?thread=${searchParams.get ('thread')}&sort=ta`;
break;
case 'evaluate-bad':
window.location.href = `./?thread=${searchParams.get ('thread')}&sort=eb`;
break;
}
}
-1290
ファイルの表示
ファイル差分が大きすぎるため省略します 差分を読込み
-104
ファイルの表示
@@ -1,104 +0,0 @@
body
{
background-color: aquamarine;
}
table
{
margin: 24px auto 40px;
}
td
{
padding: 8px;
}
table, td
{
border: solid 1px;
background-color: white;
}
#paint
{
margin-bottom: 64px;
}
#paint > div
{
margin: 24px auto;
}
h1, .illust
{
text-align: center;
}
.radio
{
/* width: 704px; */
/* display: inline-block; */
vertical-align: middle;
line-height: 1.5em;
/* margin: auto; */
}
.button-area, .canvas-area
{
text-align: center;
}
.canvas-area
{
width: 480px;
height: 480px;
max-width: 100%;
position: relative;
padding: 0;
box-sizing: content-box;
}
.canvas-area:before
{
content: "";
display: block;
padding-top: 100%;
}
.canvas-area > canvas
{
position: absolute;
left: 0;
top: 0;
border: 1px solid;
max-width: 100%;
box-sizing: content-box;
padding: 0;
margin: 0;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
text-align: center;
}
@media only screen and (max-width: 600px) {
.modal-content {
width: 70%;
}
}
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更後

幅:  |  高さ:  |  サイズ: 805 KiB

ファイルの表示
+56
ファイルの表示
@@ -0,0 +1,56 @@
<?php
require_once __DIR__ . '/../import.php';
use \Dto;
$db = new SQLite3 ('../db.sqlite3');
if (isset ($_GET['page']))
$page = $_GET['page'];
else
$page = 0;
if (isset ($_GET['thread']))
$thread = $_GET['thread'];
else
$thread = -1;
if (isset ($_GET['sort']))
{
$sort = $_GET['sort'];
if (!(in_array ($sort, array ('td', 'eg', 'ta', 'eb'))))
$sort = 'td';
}
else
$sort = 'td';
// 画像のディレクトリを開く.
$dir = './images/';
$handle = opendir ($dir);
if ($row = \Dao\Thread :: find ($db, $thread))
{
$title = $row -> title;
$explain = $row -> explain;
}
if (isset ($_GET['id']))
{
if (($_GET['evaluate'] ?? '') === 'good')
{
\Dao\Response :: like ($db, (int) $_GET['id']);
header ("Location: ./?thread=$thread&sort=$sort");
}
if (($_GET['evaluate'] ?? '') === 'bad')
{
\Dao\Response :: dislike ($db, (int) $_GET['id']);
header ("Location: ./?thread=$thread&sort=$sort");
}
}
require_once './forms/index.frm.php';
+240
ファイルの表示
@@ -0,0 +1,240 @@
html
{
font-size: 24px;
font-family: "Helvetica Neue", "Helvetica", "Segoe UI", "Arial",
"JPAGothic", "IPAGothic",
"Hiragino Sans", "Hiragino Kaku Gothic ProN",
"Yu Gothic", "Meiryo", "MS Gothic",
sans-serif;
width: 960px;
text-align: justify;
margin: auto;
punctuation-trim: adjacent;
}
em
{
font-style: normal;
font-size: 120%;
font-weight: bold;
color: red;
font-family: "Helvetica Neue", "Helvetica", "Segoe UI", "Arial",
"JPAGothic", "IPAGothic",
"Hiragino Sans", "Hiragino Kaku Gothic ProN",
"Yu Gothic", "Meiryo", "MS Gothic",
sans-serif;
}
.miteruzochan
{
white-space: nowrap;
}
section
{
margin-bottom: 3em;
}
p:not(.noindent)
{
text-indent: 1em;
}
p
{
margin: 0 2em;
line-height: 3em;
}
.copy
{
font-size: 200%;
font-weight: bold;
font-style: italic;
text-align: center;
font-family: "Times New Roman",
"JPAMincho", "IPAMincho", "Hiragino Mincho ProN",
"Yu Mincho", "MS Mincho",
serif;
margin: 1em 0;
}
footer
{
font-size: 16px;
color: dimgray;
text-align: center;
line-height: 2em;
padding-bottom: 24px;
}
footer > div
{
margin: 24px 0;
}
.copyright
{
text-align: center;
margin: 24px 0;
}
footer a
{
color: darkslategray;
}
a
{
text-decoration: none;
}
div.paragraph
{
margin-bottom: 1.5em;
}
table
{
margin: auto;
}
tr:nth-child(odd)
{
background-color: lightgray;
}
th, td
{
padding: 8px 16px;
}
#title
{
text-align: left;
display: inline-block;
}
#translate
{
text-align: right;
display: inline-block;
width: 288px;
}
header
{
display: flex;
justify-content: space-between;
align-items: center;
}
button, input
{
font-size: 24px;
}
body
{
background-color: aquamarine;
}
table
{
margin: 24px auto 40px;
}
td
{
padding: 8px;
}
table, td
{
border: solid 1px;
background-color: white;
}
#paint
{
margin-bottom: 64px;
}
#paint > div
{
margin: 24px auto;
}
h1, .illust
{
text-align: center;
}
.radio
{
/* width: 704px; */
/* display: inline-block; */
vertical-align: middle;
line-height: 1.5em;
/* margin: auto; */
}
.button-area, .canvas-area
{
text-align: center;
}
.canvas-area
{
width: 480px;
height: 480px;
max-width: 100%;
position: relative;
padding: 0;
box-sizing: content-box;
}
.canvas-area:before
{
content: "";
display: block;
padding-top: 100%;
}
.canvas-area > canvas
{
position: absolute;
left: 0;
top: 0;
border: 1px solid;
max-width: 100%;
box-sizing: content-box;
padding: 0;
margin: 0;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 400px;
text-align: center;
}
@media only screen and (max-width: 600px) {
.modal-content {
width: 70%;
}
}